diff --git a/spring-cloud-alibaba-examples/pom.xml b/spring-cloud-alibaba-examples/pom.xml index 1025b6ae..fee785d6 100644 --- a/spring-cloud-alibaba-examples/pom.xml +++ b/spring-cloud-alibaba-examples/pom.xml @@ -21,6 +21,9 @@ sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example sentinel-example/sentinel-dubbo-example/sentinel-dubbo-api + sentinel-example/sentinel-webflux-example + sentinel-example/sentinel-zuul-example + sentinel-example/sentinel-spring-cloud-gateway-example nacos-example/nacos-discovery-example nacos-example/nacos-config-example nacos-example/nacos-gateway-example diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/pom.xml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/pom.xml new file mode 100644 index 00000000..faa6889e --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/pom.xml @@ -0,0 +1,82 @@ + + + + + org.springframework.cloud + spring-cloud-alibaba-examples + 0.2.3.BUILD-SNAPSHOT + ../../pom.xml + + 4.0.0 + + + sentinel-spring-cloud-gateway-example + jar + Example demonstrating how to use sentinel with spring cloud gateway + + + + + + org.springframework.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + org.springframework.cloud + spring-cloud-alibaba-sentinel-gateway + + + + + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + + + diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MySCGConfiguration.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MySCGConfiguration.java new file mode 100644 index 00000000..0c39e3f7 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MySCGConfiguration.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import static org.springframework.web.reactive.function.BodyInserters.fromObject; + +/** + * @author Jim + */ +@Configuration +public class MySCGConfiguration { + + @Bean + public BlockRequestHandler blockRequestHandler() { + return new BlockRequestHandler() { + @Override + public Mono handleRequest(ServerWebExchange exchange, Throwable t) { + return ServerResponse.status(444) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(fromObject("SCS Sentinel block")); + } + }; + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesWebFluxController.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesWebFluxController.java new file mode 100644 index 00000000..7767a871 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesWebFluxController.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import java.util.List; +import java.util.Set; + +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +/** + * @author Jim + */ +@RestController +public class RulesWebFluxController { + + @GetMapping("/api") + public Mono> apiRules() { + return Mono.just(GatewayApiDefinitionManager.getApiDefinitions()); + } + + @GetMapping("/gateway") + public Mono> apiGateway() { + return Mono.just(GatewayRuleManager.getRules()); + } + + @GetMapping("/flow") + public Mono> apiFlow() { + return Mono.just(FlowRuleManager.getRules()); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelSpringCloudGatewayApplication.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelSpringCloudGatewayApplication.java new file mode 100644 index 00000000..786d8dcd --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelSpringCloudGatewayApplication.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Jim + */ +@SpringBootApplication +public class SentinelSpringCloudGatewayApplication { + + public static void main(String[] args) { + //GatewayCallbackManager.setRequestOriginParser(s -> "123"); + SpringApplication.run(SentinelSpringCloudGatewayApplication.class, args); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/api.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/api.json new file mode 100644 index 00000000..72a62c47 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/api.json @@ -0,0 +1,32 @@ +[ + { + "apiName": "some_customized_api", + "predicateItems": [ + { + "pattern": "/product/baz" + }, + { + "pattern": "/product/foo/**", + "matchStrategy": 1 + }, + { + "items": [ + { + "pattern": "/spring-cloud/**" + }, + { + "pattern": "/spring-cloud-alibaba/**" + } + ] + } + ] + }, + { + "apiName": "another_customized_api", + "predicateItems": [ + { + "pattern": "/ahas" + } + ] + } +] \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/application.yaml new file mode 100644 index 00000000..a614f5b7 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/application.yaml @@ -0,0 +1,37 @@ +server: + port: 18085 +spring: + application: + name: sentinel-spring-cloud-gateway + cloud: + gateway: + enabled: true + discovery: + locator: + lower-case-service-id: true + routes: + # Add your routes here. + - id: aliyun_route + uri: https://www.aliyun.com/ + predicates: + - Path=/product/** + - id: httpbin_route + uri: https://httpbin.org + predicates: + - Path=/httpbin/** + filters: + - RewritePath=/httpbin/(?.*), /$\{segment} + + sentinel: + datasource.ds2.file: + file: "classpath: gateway.json" + ruleType: gw-flow + datasource.ds1.file: + file: "classpath: api.json" + ruleType: gw-api-group + transport: + dashboard: localhost:8080 + filter: + enabled: true + +management.endpoints.web.exposure.include: "*" \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/gateway.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/gateway.json new file mode 100644 index 00000000..d8cb8744 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-spring-cloud-gateway-example/src/main/resources/gateway.json @@ -0,0 +1,22 @@ +[ + { + "resource": "some_customized_api", + "count": 1 + }, + { + "resource": "httpbin_route", + "count": 0, + "paramItem": { + "parseStrategy": 2, + "fieldName": "Spring-Cloud-Alibaba" + } + }, + { + "resource": "httpbin_route", + "count": 0, + "paramItem": { + "parseStrategy": 3, + "fieldName": "name" + } + } +] \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/pom.xml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/pom.xml new file mode 100644 index 00000000..51620b72 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/pom.xml @@ -0,0 +1,72 @@ + + + + + org.springframework.cloud + spring-cloud-alibaba-examples + 0.2.3.BUILD-SNAPSHOT + ../../pom.xml + + 4.0.0 + + + sentinel-webflux-example + jar + Example demonstrating how to use sentinel with webflux + + + + + + org.springframework.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + + + diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MyConfiguration.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MyConfiguration.java new file mode 100644 index 00000000..9d95923a --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/MyConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import static org.springframework.web.reactive.function.BodyInserters.fromObject; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; + +import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler; + +import reactor.core.publisher.Mono; + +/** + * @author Jim + */ +@Configuration +public class MyConfiguration { + + @Bean + public BlockRequestHandler blockRequestHandler() { + return new BlockRequestHandler() { + @Override + public Mono handleRequest(ServerWebExchange exchange, + Throwable t) { + return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(fromObject("block")); + } + }; + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxApplication.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxApplication.java new file mode 100644 index 00000000..87a42503 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxApplication.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Jim + */ +@SpringBootApplication +public class SentinelWebFluxApplication { + + public static void main(String[] args) { + SpringApplication.run(SentinelWebFluxApplication.class, args); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxController.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxController.java new file mode 100644 index 00000000..86eae3f6 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelWebFluxController.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer; +import com.alibaba.csp.sentinel.annotation.SentinelResource; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * @author Jim + */ +@RestController +public class SentinelWebFluxController { + + @GetMapping("/mono") + public Mono mono() { + return Mono.just("simple string") + // transform the publisher here. + .transform(new SentinelReactorTransformer<>("mono")); + } + + @GetMapping("/flux") + public Flux flux() { + return Flux.fromArray(new String[] { "a", "b", "c" }) + // transform the publisher here. + .transform(new SentinelReactorTransformer<>("flux")); + } + + @GetMapping("/aaa") + @SentinelResource("abc") + public Flux aaa() { + return Flux.fromArray(new String[] { "a", "b", "c" }) + // transform the publisher here. + .transform(new SentinelReactorTransformer<>("aaa")); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/application.properties new file mode 100644 index 00000000..e9750c02 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.application.name=sentinel-example +server.port=18084 +management.endpoints.web.exposure.include=* +spring.cloud.sentinel.transport.dashboard=localhost:8080 +spring.cloud.sentinel.eager=true + + +spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json +spring.cloud.sentinel.datasource.ds1.file.data-type=json +spring.cloud.sentinel.datasource.ds1.file.rule-type=flow \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/flowrule.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/flowrule.json new file mode 100644 index 00000000..422343cc --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-webflux-example/src/main/resources/flowrule.json @@ -0,0 +1,27 @@ +[ + { + "resource": "/mono", + "controlBehavior": 0, + "count": 0, + "grade": 1, + "limitApp": "default", + "strategy": 0 + }, + { + "resource": "/flux", + "controlBehavior": 0, + "count": 0, + "grade": 1, + "limitApp": "default", + "strategy": 0 + } +, + { + "resource": "abc", + "controlBehavior": 0, + "count": 0, + "grade": 1, + "limitApp": "default", + "strategy": 0 + } +] \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/pom.xml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/pom.xml new file mode 100644 index 00000000..01c18217 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/pom.xml @@ -0,0 +1,83 @@ + + + + + org.springframework.cloud + spring-cloud-alibaba-examples + 0.2.3.BUILD-SNAPSHOT + ../../pom.xml + + 4.0.0 + + + sentinel-zuul-example + jar + Example demonstrating how to use sentinel with zuul + + + + + + org.springframework.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + + + + org.springframework.cloud + spring-cloud-alibaba-sentinel-gateway + + + + + + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + + + diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesController.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesController.java new file mode 100644 index 00000000..01411ab7 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RulesController.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import java.util.List; +import java.util.Set; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; + +/** + * @author Jim + */ +@RestController +public class RulesController { + + @GetMapping("/api") + public Set apiRules() { + return GatewayApiDefinitionManager.getApiDefinitions(); + } + + @GetMapping("/gateway") + public Set apiGateway() { + return GatewayRuleManager.getRules(); + } + + @GetMapping("/flow") + public List apiFlow() { + return FlowRuleManager.getRules(); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelZuulApplication.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelZuulApplication.java new file mode 100644 index 00000000..7e99e220 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/SentinelZuulApplication.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; + +/** + * @author Jim + */ +@SpringBootApplication +@EnableZuulProxy +public class SentinelZuulApplication { + + public static void main(String[] args) { + SpringApplication.run(SentinelZuulApplication.class, args); + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ZuulConfiguration.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ZuulConfiguration.java new file mode 100644 index 00000000..796241a2 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ZuulConfiguration.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.alibaba.cloud.examples; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.RequestOriginParser; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.BlockResponse; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackProvider; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Jim + */ +@Configuration +public class ZuulConfiguration { + + @Bean + public ZuulBlockFallbackProvider zuulBlockFallbackProvider1() { + return new ZuulBlockFallbackProvider() { + @Override + public String getRoute() { + return "*"; + } + + @Override + public BlockResponse fallbackResponse(String route, Throwable cause) { + if (route.equals("my-service3")) { + return new BlockResponse(433, "Sentinel Block3", route); + } else if (route.equals("my-service4")) { + return new BlockResponse(444, "my-service4", route); + } else { + return new BlockResponse(499, "Sentinel Block 499", route); + } + } + }; + } + + @Bean + public RequestOriginParser requestOriginParser() { + return new RequestOriginParser() { + + @Override + public String parseOrigin(HttpServletRequest request) { + return "123"; + } + }; + } + +} diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/api.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/api.json new file mode 100644 index 00000000..72a62c47 --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/api.json @@ -0,0 +1,32 @@ +[ + { + "apiName": "some_customized_api", + "predicateItems": [ + { + "pattern": "/product/baz" + }, + { + "pattern": "/product/foo/**", + "matchStrategy": 1 + }, + { + "items": [ + { + "pattern": "/spring-cloud/**" + }, + { + "pattern": "/spring-cloud-alibaba/**" + } + ] + } + ] + }, + { + "apiName": "another_customized_api", + "predicateItems": [ + { + "pattern": "/ahas" + } + ] + } +] \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/application.yaml new file mode 100644 index 00000000..0e9d9abf --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/application.yaml @@ -0,0 +1,40 @@ +server: + port: 18086 +spring: + application: + name: sentinel-zuul + cloud: + sentinel: + datasource.ds2.file: + file: "classpath: gateway.json" + ruleType: gw-flow + datasource.ds1.file: + file: "classpath: api.json" + ruleType: gw-api-group + transport: + dashboard: localhost:8080 + filter: + enabled: false + +management.endpoints.web.exposure.include: "*" + + +zuul.routes.my-service.path: "/product/foo/**" +zuul.routes.my-service.service-id: "my-service" + +zuul.routes.my-service2.path: "/my-service2/**" +zuul.routes.my-service2.service-id: "my-service2" + +zuul.routes.my-service3.path: "/my-service3/**" +zuul.routes.my-service3.service-id: "my-service3" + +zuul.routes.my-service4.path: "/my-service4/**" +zuul.routes.my-service4.service-id: "my-service4" + + +spring.cloud.sentinel.zuul.order.pre: 2000 +spring.cloud.sentinel.zuul.order.post: 500 +spring.cloud.sentinel.zuul.order.error: -100 + + +spring.cloud.sentinel.zuul.enabled: true \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/gateway.json b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/gateway.json new file mode 100644 index 00000000..d55265ea --- /dev/null +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-zuul-example/src/main/resources/gateway.json @@ -0,0 +1,26 @@ +[ + { + "resource": "some_customized_api", + "count": 0 + }, + { + "resource": "my-service2", + "count": 0 + }, + { + "resource": "my-service3", + "count": 0, + "paramItem": { + "parseStrategy": 2, + "fieldName": "Spring-Cloud-Alibaba" + } + }, + { + "resource": "my-service4", + "count": 0, + "paramItem": { + "parseStrategy": 3, + "fieldName": "name" + } + } +] \ No newline at end of file diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java index 46b10431..00f7576e 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java @@ -261,12 +261,12 @@ public class SentinelAutoConfiguration { return new JsonConverter(objectMapper, ParamFlowRule.class); } - @Bean("sentinel-json-gateway-flow-converter") + @Bean("sentinel-json-gw-flow-converter") public JsonConverter jsonGatewayFlowConverter() { return new JsonConverter(objectMapper, GatewayFlowRule.class); } - @Bean("sentinel-json-api-converter") + @Bean("sentinel-json-gw-api-group-converter") public JsonConverter jsonApiConverter() { return new JsonConverter(objectMapper, ApiDefinition.class); } @@ -318,12 +318,12 @@ public class SentinelAutoConfiguration { return new XmlConverter(xmlMapper, ParamFlowRule.class); } - @Bean("sentinel-xml-gateway-flow-converter") + @Bean("sentinel-xml-gw-flow-converter") public XmlConverter xmlGatewayFlowConverter() { return new XmlConverter(xmlMapper, GatewayFlowRule.class); } - @Bean("sentinel-xml-api-converter") + @Bean("sentinel-xml-gw-api-group-converter") public XmlConverter xmlApiConverter() { return new XmlConverter(xmlMapper, ApiDefinition.class); } diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/feign/SentinelInvocationHandler.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/feign/SentinelInvocationHandler.java index acd7cdea..54636509 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/feign/SentinelInvocationHandler.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/feign/SentinelInvocationHandler.java @@ -91,8 +91,8 @@ public class SentinelInvocationHandler implements InvocationHandler { if (target instanceof Target.HardCodedTarget) { Target.HardCodedTarget hardCodedTarget = (Target.HardCodedTarget) target; MethodMetadata methodMetadata = SentinelContractHolder.metadataMap - .get(method.getDeclaringClass().getName() - + Feign.configKey(method.getDeclaringClass(), method)); + .get(hardCodedTarget.type().getName() + + Feign.configKey(hardCodedTarget.type(), method)); // resource default is HttpMethod:protocol://url String resourceName = methodMetadata.template().method().toUpperCase() + ":" + hardCodedTarget.url() + methodMetadata.template().url(); diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java index b7d03670..5a3a8471 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java @@ -16,9 +16,14 @@ package org.springframework.cloud.alibaba.sentinel; -import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -35,13 +40,9 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; /** * @author Jim @@ -60,6 +61,9 @@ public class SentinelFeignTests { @Autowired private BarService barService; + @Autowired + private BazService bazService; + @Before public void setUp() { FlowRule rule1 = new FlowRule(); @@ -83,7 +87,14 @@ public class SentinelFeignTests { rule3.setLimitApp("default"); rule3.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); rule3.setStrategy(RuleConstant.STRATEGY_DIRECT); - FlowRuleManager.loadRules(Arrays.asList(rule1, rule2, rule3)); + FlowRule rule4 = new FlowRule(); + rule4.setGrade(RuleConstant.FLOW_GRADE_QPS); + rule4.setCount(0); + rule4.setResource("GET:http://baz-service/baz"); + rule4.setLimitApp("default"); + rule4.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); + rule4.setStrategy(RuleConstant.STRATEGY_DIRECT); + FlowRuleManager.loadRules(Arrays.asList(rule1, rule2, rule3, rule4)); } @Test @@ -101,6 +112,9 @@ public class SentinelFeignTests { assertThatExceptionOfType(Exception.class).isThrownBy(() -> { barService.bar(); }); + assertThatExceptionOfType(Exception.class).isThrownBy(() -> { + bazService.baz(); + }); assertNotEquals("ToString method invoke was not in SentinelInvocationHandler", echoService.toString(), fooService.toString()); @@ -146,6 +160,15 @@ public class SentinelFeignTests { String bar(); } + public interface BazService { + @RequestMapping(path = "baz") + String baz(); + } + + @FeignClient(value = "baz-service") + public interface BazClient extends BazService { + } + public static class EchoServiceFallback implements EchoService { @Override