diff --git a/pom.xml b/pom.xml index f1aca043..c582e9fd 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ spring-cloud-alibaba-dependencies spring-cloud-alibaba-sentinel spring-cloud-alibaba-sentinel-datasource - spring-cloud-alibaba-sentinel-zuul + spring-cloud-alibaba-sentinel-gateway spring-cloud-alibaba-nacos-config spring-cloud-alibaba-nacos-discovery spring-cloud-alibaba-seata diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml index ff8230c7..4ab6d0fa 100644 --- a/spring-cloud-alibaba-dependencies/pom.xml +++ b/spring-cloud-alibaba-dependencies/pom.xml @@ -16,7 +16,7 @@ Spring Cloud Alibaba Dependencies - 1.5.2 + 1.6.0 3.1.0 1.0.0 0.4.2 @@ -140,6 +140,11 @@ sentinel-zuul-adapter ${sentinel.version} + + com.alibaba.csp + sentinel-spring-cloud-gateway-adapter + ${sentinel.version} + com.alibaba.csp sentinel-transport-simple-http @@ -175,13 +180,21 @@ sentinel-cluster-client-default ${sentinel.version} + + com.alibaba.csp + sentinel-api-gateway-adapter-common + ${sentinel.version} + - + + + + - com.alibaba.fescar - fescar-spring - ${fescar.version} + io.seata + seata-spring + ${seata.version} @@ -230,6 +243,11 @@ spring-cloud-alibaba-sentinel-datasource ${project.version} + + org.springframework.cloud + spring-cloud-alibaba-sentinel-gateway + ${project.version} + org.springframework.cloud spring-cloud-alicloud-oss diff --git a/spring-cloud-alibaba-examples/pom.xml b/spring-cloud-alibaba-examples/pom.xml index 1bce3d15..fd47150a 100644 --- a/spring-cloud-alibaba-examples/pom.xml +++ b/spring-cloud-alibaba-examples/pom.xml @@ -20,6 +20,7 @@ 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-zuul-example nacos-example/nacos-discovery-example nacos-example/nacos-config-example oss-example 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..b6ed6653 --- /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.1.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..0942cda3 --- /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..cd01e3c7 --- /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,68 @@ +/* + * 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 org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +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; + +/** + * @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-datasource/pom.xml b/spring-cloud-alibaba-sentinel-datasource/pom.xml index a3c301c7..f1502add 100644 --- a/spring-cloud-alibaba-sentinel-datasource/pom.xml +++ b/spring-cloud-alibaba-sentinel-datasource/pom.xml @@ -27,6 +27,12 @@ true + + com.alibaba.csp + sentinel-api-gateway-adapter-common + true + + com.alibaba.csp sentinel-datasource-nacos diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java index e64c360c..a5004d83 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/RuleType.java @@ -19,6 +19,8 @@ package org.springframework.cloud.alibaba.sentinel.datasource; import org.springframework.cloud.alibaba.sentinel.datasource.config.AbstractDataSourceProperties; import org.springframework.util.StringUtils; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; import com.alibaba.csp.sentinel.slots.block.AbstractRule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; @@ -53,7 +55,15 @@ public enum RuleType { /** * authority */ - AUTHORITY("authority", AuthorityRule.class); + AUTHORITY("authority", AuthorityRule.class), + /** + * gateway flow + */ + GW_FLOW("gw-flow", GatewayFlowRule.class), + /** + * api + */ + GW_API_GROUP("gw-api-group", ApiDefinition.class); /** * alias for {@link AbstractRule} diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java index 7b6f5a49..4179d28c 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/AbstractDataSourceProperties.java @@ -19,7 +19,10 @@ package org.springframework.cloud.alibaba.sentinel.datasource.config; import javax.validation.constraints.NotNull; import org.springframework.cloud.alibaba.sentinel.datasource.RuleType; +import org.springframework.core.env.Environment; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager; import com.alibaba.csp.sentinel.datasource.AbstractDataSource; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; @@ -43,6 +46,8 @@ public class AbstractDataSourceProperties { private String converterClass; @JsonIgnore private final String factoryBeanName; + @JsonIgnore + private Environment env; public AbstractDataSourceProperties(String factoryBeanName) { this.factoryBeanName = factoryBeanName; @@ -76,6 +81,14 @@ public class AbstractDataSourceProperties { return factoryBeanName; } + protected Environment getEnv() { + return env; + } + + public void setEnv(Environment env) { + this.env = env; + } + public void preCheck(String dataSourceName) { } @@ -97,6 +110,12 @@ public class AbstractDataSourceProperties { case AUTHORITY: AuthorityRuleManager.register2Property(dataSource.getProperty()); break; + case GW_FLOW: + GatewayRuleManager.register2Property(dataSource.getProperty()); + break; + case GW_API_GROUP: + GatewayApiDefinitionManager.register2Property(dataSource.getProperty()); + break; default: break; } diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java index fd5eb195..be835040 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java @@ -48,9 +48,13 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties { @Override public void preCheck(String dataSourceName) { - if (StringUtils.isEmpty(serverAddr) && acmPropertiesInvalid()) { - throw new IllegalArgumentException( - "NacosDataSource properties value not correct. serverAddr is empty but there is empty value in accessKey, secretKey, endpoint, namespace property"); + if (StringUtils.isEmpty(serverAddr)) { + serverAddr = this.getEnv().getProperty( + "spring.cloud.sentinel.datasource.nacos.server-addr", ""); + if (StringUtils.isEmpty(serverAddr)) { + throw new IllegalArgumentException( + "NacosDataSource server-addr is empty"); + } } } @@ -110,9 +114,4 @@ public class NacosDataSourceProperties extends AbstractDataSourceProperties { this.secretKey = secretKey; } - public boolean acmPropertiesInvalid() { - return StringUtils.isEmpty(endpoint) || StringUtils.isEmpty(accessKey) - || StringUtils.isEmpty(secretKey) || StringUtils.isEmpty(namespace); - } - } diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/ZookeeperDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/ZookeeperDataSourceProperties.java index 6138b872..6cbff41e 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/ZookeeperDataSourceProperties.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/ZookeeperDataSourceProperties.java @@ -19,6 +19,7 @@ package org.springframework.cloud.alibaba.sentinel.datasource.config; import javax.validation.constraints.NotNull; import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.ZookeeperDataSourceFactoryBean; +import org.springframework.util.StringUtils; /** * Zookeeper Properties class Using by {@link DataSourcePropertiesConfiguration} and @@ -32,7 +33,6 @@ public class ZookeeperDataSourceProperties extends AbstractDataSourceProperties super(ZookeeperDataSourceFactoryBean.class.getName()); } - @NotNull private String serverAddr; private String path; @@ -41,6 +41,18 @@ public class ZookeeperDataSourceProperties extends AbstractDataSourceProperties private String dataId; + @Override + public void preCheck(String dataSourceName) { + if (StringUtils.isEmpty(serverAddr)) { + serverAddr = this.getEnv() + .getProperty("spring.cloud.sentinel.datasource.zk.server-addr", ""); + if (StringUtils.isEmpty(serverAddr)) { + throw new IllegalArgumentException( + "ZookeeperDataSource server-addr is empty"); + } + } + } + public String getServerAddr() { return serverAddr; } diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java index 06d2f65b..2f7ad975 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/SentinelConverter.java @@ -17,7 +17,9 @@ package org.springframework.cloud.alibaba.sentinel.datasource.converter; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import org.slf4j.Logger; @@ -25,8 +27,9 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.alibaba.sentinel.datasource.RuleType; import org.springframework.util.StringUtils; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; import com.alibaba.csp.sentinel.datasource.Converter; -import com.alibaba.csp.sentinel.slots.block.AbstractRule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; @@ -50,8 +53,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @see ParamFlowRule * @see ObjectMapper */ -public abstract class SentinelConverter - implements Converter> { +public abstract class SentinelConverter + implements Converter> { private static final Logger log = LoggerFactory.getLogger(SentinelConverter.class); @@ -65,11 +68,20 @@ public abstract class SentinelConverter } @Override - public List convert(String source) { - List ruleList = new ArrayList<>(); + public Collection convert(String source) { + Collection ruleCollection; + + // hard code + if (ruleClass == GatewayFlowRule.class || ruleClass == ApiDefinition.class) { + ruleCollection = new HashSet<>(); + } + else { + ruleCollection = new ArrayList<>(); + } + if (StringUtils.isEmpty(source)) { log.warn("converter can not convert rules because source is empty"); - return ruleList; + return ruleCollection; } try { List sourceArray = objectMapper.readValue(source, @@ -85,15 +97,15 @@ public abstract class SentinelConverter // won't be happen } - AbstractRule rule = convertRule(item); + Object rule = convertRule(item); if (rule != null) { - ruleList.add(rule); + ruleCollection.add(rule); } } - if (ruleList.size() != sourceArray.size()) { - throw new IllegalArgumentException("convert " + ruleList.size() + if (ruleCollection.size() != sourceArray.size()) { + throw new IllegalArgumentException("convert " + ruleCollection.size() + " rules but there are " + sourceArray.size() + " rules from datasource. RuleClass: " + ruleClass.getSimpleName()); @@ -102,12 +114,12 @@ public abstract class SentinelConverter catch (Exception e) { throw new RuntimeException("convert error: " + e.getMessage(), e); } - return ruleList; + return ruleCollection; } - private AbstractRule convertRule(String ruleStr) { + private Object convertRule(String ruleStr) { try { - final AbstractRule rule = objectMapper.readValue(ruleStr, ruleClass); + final Object rule = objectMapper.readValue(ruleStr, ruleClass); RuleType ruleType = RuleType.getByClass(ruleClass); switch (ruleType) { case FLOW: diff --git a/spring-cloud-alibaba-sentinel-zuul/pom.xml b/spring-cloud-alibaba-sentinel-gateway/pom.xml similarity index 92% rename from spring-cloud-alibaba-sentinel-zuul/pom.xml rename to spring-cloud-alibaba-sentinel-gateway/pom.xml index 1b5305b1..d943b976 100644 --- a/spring-cloud-alibaba-sentinel-zuul/pom.xml +++ b/spring-cloud-alibaba-sentinel-gateway/pom.xml @@ -10,8 +10,8 @@ 4.0.0 org.springframework.cloud - spring-cloud-alibaba-sentinel-zuul - Spring Cloud Alibaba Sentinel Zuul + spring-cloud-alibaba-sentinel-gateway + Spring Cloud Alibaba Sentinel Gateway diff --git a/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java new file mode 100644 index 00000000..a5755b96 --- /dev/null +++ b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java @@ -0,0 +1,117 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * 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 + * + * http://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.sentinel.zuul; + +import javax.annotation.PostConstruct; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.alibaba.sentinel.zuul.handler.FallBackProviderHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.RequestOriginParser; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.callback.ZuulGatewayCallbackManager; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter; + +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.http.ZuulServlet; + +/** + * Sentinel Spring Cloud Zuul AutoConfiguration + * + * @author tiger + */ +@Configuration +@ConditionalOnClass(ZuulServlet.class) +@ConditionalOnProperty(prefix = SentinelZuulAutoConfiguration.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) +public class SentinelZuulAutoConfiguration { + + private static final Logger logger = LoggerFactory + .getLogger(SentinelZuulAutoConfiguration.class); + + public static final String PREFIX = "spring.cloud.sentinel.zuul"; + + @Autowired + private Environment environment; + + @Autowired(required = false) + private RequestOriginParser requestOriginParser; + + @PostConstruct + private void init() { + if (requestOriginParser != null) { + ZuulGatewayCallbackManager.setOriginParser(requestOriginParser); + } + } + + @Bean + public ZuulFilter sentinelZuulPreFilter() { + String preOrderStr = environment.getProperty(PREFIX + "." + "order.pre"); + int order = 10000; + try { + order = Integer.parseInt(preOrderStr); + } + catch (NumberFormatException e) { + // ignore + } + logger.info("[Sentinel Zuul] register SentinelZuulPreFilter {}", order); + return new SentinelZuulPreFilter(order); + } + + @Bean + public ZuulFilter sentinelZuulPostFilter() { + String postOrderStr = environment.getProperty(PREFIX + "." + "order.post"); + int order = 1000; + try { + order = Integer.parseInt(postOrderStr); + } + catch (NumberFormatException e) { + // ignore + } + logger.info("[Sentinel Zuul] register SentinelZuulPostFilter {}", order); + return new SentinelZuulPostFilter(order); + } + + @Bean + public ZuulFilter sentinelZuulErrorFilter() { + String errorOrderStr = environment.getProperty(PREFIX + "." + "order.error"); + int order = -1; + try { + order = Integer.parseInt(errorOrderStr); + } + catch (NumberFormatException e) { + // ignore + } + logger.info("[Sentinel Zuul] register SentinelZuulErrorFilter {}", order); + return new SentinelZuulErrorFilter(order); + } + + @Bean + public FallBackProviderHandler fallBackProviderHandler( + DefaultListableBeanFactory beanFactory) { + return new FallBackProviderHandler(beanFactory); + } + +} diff --git a/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java similarity index 77% rename from spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java rename to spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java index b7c97496..8dc3dc2c 100644 --- a/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java +++ b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/handler/FallBackProviderHandler.java @@ -2,15 +2,15 @@ package org.springframework.cloud.alibaba.sentinel.zuul.handler; import java.util.Map; -import org.apache.commons.collections.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.util.CollectionUtils; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.DefaultBlockFallbackProvider; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.ZuulBlockFallbackManager; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.ZuulBlockFallbackProvider; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.DefaultBlockFallbackProvider; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackManager; +import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackProvider; /** * @author tiger @@ -30,7 +30,7 @@ public class FallBackProviderHandler implements SmartInitializingSingleton { public void afterSingletonsInstantiated() { Map providerMap = beanFactory .getBeansOfType(ZuulBlockFallbackProvider.class); - if (MapUtils.isNotEmpty(providerMap)) { + if (!CollectionUtils.isEmpty(providerMap)) { for (String k : providerMap.keySet()) { logger.info("[Sentinel Zuul] Register provider name:{}, instance: {}", k, providerMap.get(k)); diff --git a/spring-cloud-alibaba-sentinel-zuul/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-alibaba-sentinel-zuul/src/main/resources/META-INF/spring.factories rename to spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java b/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java deleted file mode 100644 index 4296f2cb..00000000 --- a/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * 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 - * - * http://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.sentinel.zuul; - -import static org.springframework.cloud.alibaba.sentinel.zuul.SentinelZuulAutoConfiguration.PREFIX; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.alibaba.sentinel.zuul.handler.FallBackProviderHandler; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -import com.alibaba.csp.sentinel.adapter.zuul.fallback.DefaultRequestOriginParser; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.DefaultUrlCleaner; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.RequestOriginParser; -import com.alibaba.csp.sentinel.adapter.zuul.fallback.UrlCleaner; -import com.alibaba.csp.sentinel.adapter.zuul.filters.SentinelErrorFilter; -import com.alibaba.csp.sentinel.adapter.zuul.filters.SentinelPostFilter; -import com.alibaba.csp.sentinel.adapter.zuul.filters.SentinelPreFilter; -import com.alibaba.csp.sentinel.adapter.zuul.properties.SentinelZuulProperties; -import com.alibaba.csp.sentinel.util.StringUtil; - -import com.netflix.zuul.ZuulFilter; - -/** - * Sentinel Spring Cloud Zuul AutoConfiguration - * - * @author tiger - */ -@Configuration -@ConditionalOnProperty(prefix = PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) -public class SentinelZuulAutoConfiguration { - - @Autowired - private Environment environment; - - public static final String PREFIX = "spring.cloud.sentinel.zuul"; - - @Bean - public SentinelZuulProperties sentinelZuulProperties() { - SentinelZuulProperties properties = new SentinelZuulProperties(); - String enabledStr = environment.getProperty(PREFIX + "." + "enabled"); - String preOrderStr = environment.getProperty(PREFIX + "." + "order.pre"); - String postOrderStr = environment.getProperty(PREFIX + "." + "order.post"); - String errorOrderStr = environment.getProperty(PREFIX + "." + "order.error"); - if (StringUtil.isNotEmpty(enabledStr)) { - Boolean enabled = Boolean.valueOf(enabledStr); - properties.setEnabled(enabled); - } - if (StringUtil.isNotEmpty(preOrderStr)) { - properties.getOrder().setPre(Integer.parseInt(preOrderStr)); - } - if (StringUtil.isNotEmpty(postOrderStr)) { - properties.getOrder().setPost(Integer.parseInt(postOrderStr)); - } - if (StringUtil.isNotEmpty(errorOrderStr)) { - properties.getOrder().setError(Integer.parseInt(errorOrderStr)); - } - return properties; - } - - @Bean - @ConditionalOnMissingBean(UrlCleaner.class) - public UrlCleaner urlCleaner() { - return new DefaultUrlCleaner(); - } - - @Bean - @ConditionalOnMissingBean(RequestOriginParser.class) - public RequestOriginParser requestOriginParser() { - return new DefaultRequestOriginParser(); - } - - @Bean - public ZuulFilter preFilter(SentinelZuulProperties sentinelZuulProperties, - UrlCleaner urlCleaner, RequestOriginParser requestOriginParser) { - return new SentinelPreFilter(sentinelZuulProperties, urlCleaner, - requestOriginParser); - } - - @Bean - public ZuulFilter postFilter(SentinelZuulProperties sentinelZuulProperties) { - return new SentinelPostFilter(sentinelZuulProperties); - } - - @Bean - public ZuulFilter errorFilter(SentinelZuulProperties sentinelZuulProperties) { - return new SentinelErrorFilter(sentinelZuulProperties); - } - - @Bean - public FallBackProviderHandler fallBackProviderListener( - DefaultListableBeanFactory beanFactory) { - return new FallBackProviderHandler(beanFactory); - } - -} \ No newline at end of file diff --git a/spring-cloud-alibaba-sentinel/pom.xml b/spring-cloud-alibaba-sentinel/pom.xml index ebe05db0..d5081390 100644 --- a/spring-cloud-alibaba-sentinel/pom.xml +++ b/spring-cloud-alibaba-sentinel/pom.xml @@ -81,6 +81,11 @@ provided + + com.alibaba.csp + sentinel-api-gateway-adapter-common + + 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 ec361c25..f8f914c2 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 @@ -16,6 +16,12 @@ package org.springframework.cloud.alibaba.sentinel.custom; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; @@ -31,8 +37,14 @@ import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConver import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateGroupItem; +import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem; +import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule; import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler; import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner; @@ -50,7 +62,15 @@ import com.alibaba.csp.sentinel.slots.system.SystemRule; import com.alibaba.csp.sentinel.transport.config.TransportConfig; import com.alibaba.csp.sentinel.util.AppNameUtil; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; /** @@ -174,72 +194,164 @@ public class SentinelAutoConfiguration { @Bean public SentinelDataSourceHandler sentinelDataSourceHandler( - DefaultListableBeanFactory beanFactory) { - return new SentinelDataSourceHandler(beanFactory); + DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, + Environment env) { + return new SentinelDataSourceHandler(beanFactory, sentinelProperties, env); } @ConditionalOnClass(ObjectMapper.class) + @Configuration protected static class SentinelConverterConfiguration { - private ObjectMapper objectMapper = new ObjectMapper(); + static class ApiPredicateItemDeserializer + extends StdDeserializer { + private Map> registry = new HashMap>(); - @Bean("sentinel-json-flow-converter") - public JsonConverter jsonFlowConverter() { - return new JsonConverter(objectMapper, FlowRule.class); + ApiPredicateItemDeserializer() { + super(ApiPredicateItem.class); + } + + void registerApiPredicateItem(String uniqueAttribute, + Class apiPredicateItemClass) { + registry.put(uniqueAttribute, apiPredicateItemClass); + } + + @Override + public ApiPredicateItem deserialize(JsonParser jp, + DeserializationContext ctxt) throws IOException { + ObjectMapper mapper = (ObjectMapper) jp.getCodec(); + ObjectNode root = mapper.readTree(jp); + Class apiPredicateItemClass = null; + Iterator> elementsIterator = root.fields(); + while (elementsIterator.hasNext()) { + Entry element = elementsIterator.next(); + String name = element.getKey(); + if (registry.containsKey(name)) { + apiPredicateItemClass = registry.get(name); + break; + } + } + if (apiPredicateItemClass == null) { + return null; + } + return mapper.readValue(root.toString(), apiPredicateItemClass); + } } - @Bean("sentinel-json-degrade-converter") - public JsonConverter jsonDegradeConverter() { - return new JsonConverter(objectMapper, DegradeRule.class); + @Configuration + protected static class SentinelJsonConfiguration { + + private ObjectMapper objectMapper = new ObjectMapper(); + + public SentinelJsonConfiguration() { + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + + ApiPredicateItemDeserializer deserializer = new ApiPredicateItemDeserializer(); + deserializer.registerApiPredicateItem("pattern", + ApiPathPredicateItem.class); + deserializer.registerApiPredicateItem("items", + ApiPredicateGroupItem.class); + SimpleModule module = new SimpleModule( + "PolymorphicApiPredicateItemDeserializerModule", + new Version(1, 0, 0, null)); + module.addDeserializer(ApiPredicateItem.class, deserializer); + objectMapper.registerModule(module); + } + + @Bean("sentinel-json-flow-converter") + public JsonConverter jsonFlowConverter() { + return new JsonConverter(objectMapper, FlowRule.class); + } + + @Bean("sentinel-json-degrade-converter") + public JsonConverter jsonDegradeConverter() { + return new JsonConverter(objectMapper, DegradeRule.class); + } + + @Bean("sentinel-json-system-converter") + public JsonConverter jsonSystemConverter() { + return new JsonConverter(objectMapper, SystemRule.class); + } + + @Bean("sentinel-json-authority-converter") + public JsonConverter jsonAuthorityConverter() { + return new JsonConverter(objectMapper, AuthorityRule.class); + } + + @Bean("sentinel-json-param-flow-converter") + public JsonConverter jsonParamFlowConverter() { + return new JsonConverter(objectMapper, ParamFlowRule.class); + } + + @Bean("sentinel-json-gw-flow-converter") + public JsonConverter jsonGatewayFlowConverter() { + return new JsonConverter(objectMapper, GatewayFlowRule.class); + } + + @Bean("sentinel-json-gw-api-group-converter") + public JsonConverter jsonApiConverter() { + return new JsonConverter(objectMapper, ApiDefinition.class); + } } - @Bean("sentinel-json-system-converter") - public JsonConverter jsonSystemConverter() { - return new JsonConverter(objectMapper, SystemRule.class); + @ConditionalOnClass(XmlMapper.class) + @Configuration + protected static class SentinelXmlConfiguration { + + private XmlMapper xmlMapper = new XmlMapper(); + + public SentinelXmlConfiguration() { + xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + ApiPredicateItemDeserializer deserializer = new ApiPredicateItemDeserializer(); + deserializer.registerApiPredicateItem("pattern", + ApiPathPredicateItem.class); + deserializer.registerApiPredicateItem("items", + ApiPredicateGroupItem.class); + SimpleModule module = new SimpleModule( + "PolymorphicGatewayDeserializerModule", + new Version(1, 0, 0, null)); + module.addDeserializer(ApiPredicateItem.class, deserializer); + xmlMapper.registerModule(module); + } + + @Bean("sentinel-xml-flow-converter") + public XmlConverter xmlFlowConverter() { + return new XmlConverter(xmlMapper, FlowRule.class); + } + + @Bean("sentinel-xml-degrade-converter") + public XmlConverter xmlDegradeConverter() { + return new XmlConverter(xmlMapper, DegradeRule.class); + } + + @Bean("sentinel-xml-system-converter") + public XmlConverter xmlSystemConverter() { + return new XmlConverter(xmlMapper, SystemRule.class); + } + + @Bean("sentinel-xml-authority-converter") + public XmlConverter xmlAuthorityConverter() { + return new XmlConverter(xmlMapper, AuthorityRule.class); + } + + @Bean("sentinel-xml-param-flow-converter") + public XmlConverter xmlParamFlowConverter() { + return new XmlConverter(xmlMapper, ParamFlowRule.class); + } + + @Bean("sentinel-xml-gw-flow-converter") + public XmlConverter xmlGatewayFlowConverter() { + return new XmlConverter(xmlMapper, GatewayFlowRule.class); + } + + @Bean("sentinel-xml-gw-api-group-converter") + public XmlConverter xmlApiConverter() { + return new XmlConverter(xmlMapper, ApiDefinition.class); + } + } - - @Bean("sentinel-json-authority-converter") - public JsonConverter jsonAuthorityConverter() { - return new JsonConverter(objectMapper, AuthorityRule.class); - } - - @Bean("sentinel-json-param-flow-converter") - public JsonConverter jsonParamFlowConverter() { - return new JsonConverter(objectMapper, ParamFlowRule.class); - } - - } - - @ConditionalOnClass(XmlMapper.class) - protected static class SentinelXmlConfiguration { - - private XmlMapper xmlMapper = new XmlMapper(); - - @Bean("sentinel-xml-flow-converter") - public XmlConverter xmlFlowConverter() { - return new XmlConverter(xmlMapper, FlowRule.class); - } - - @Bean("sentinel-xml-degrade-converter") - public XmlConverter xmlDegradeConverter() { - return new XmlConverter(xmlMapper, DegradeRule.class); - } - - @Bean("sentinel-xml-system-converter") - public XmlConverter xmlSystemConverter() { - return new XmlConverter(xmlMapper, SystemRule.class); - } - - @Bean("sentinel-xml-authority-converter") - public XmlConverter xmlAuthorityConverter() { - return new XmlConverter(xmlMapper, AuthorityRule.class); - } - - @Bean("sentinel-xml-param-flow-converter") - public XmlConverter xmlParamFlowConverter() { - return new XmlConverter(xmlMapper, ParamFlowRule.class); - } - } } diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java index 9e79ec48..696a8c54 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelDataSourceHandler.java @@ -18,14 +18,15 @@ package org.springframework.cloud.alibaba.sentinel.custom; import java.lang.reflect.Field; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.SmartInitializingSingleton; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.cloud.alibaba.sentinel.SentinelProperties; @@ -33,6 +34,7 @@ import org.springframework.cloud.alibaba.sentinel.datasource.config.AbstractData import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration; import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter; import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter; +import org.springframework.core.env.Environment; import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -63,12 +65,16 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { private final DefaultListableBeanFactory beanFactory; - public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory) { - this.beanFactory = beanFactory; - } + private final SentinelProperties sentinelProperties; - @Autowired - private SentinelProperties sentinelProperties; + private final Environment env; + + public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, + SentinelProperties sentinelProperties, Environment env) { + this.beanFactory = beanFactory; + this.sentinelProperties = sentinelProperties; + this.env = env; + } @Override public void afterSingletonsInstantiated() { @@ -85,6 +91,7 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { } AbstractDataSourceProperties abstractDataSourceProperties = dataSourceProperties .getValidDataSourceProperties(); + abstractDataSourceProperties.setEnv(env); abstractDataSourceProperties.preCheck(dataSourceName); registerBean(abstractDataSourceProperties, dataSourceName + "-sentinel-" + validFields.get(0) + "-datasource"); @@ -221,8 +228,8 @@ public class SentinelDataSourceHandler implements SmartInitializingSingleton { + " loadConfig error: " + e.getMessage(), e); return; } - if (ruleConfig instanceof List) { - List convertedRuleList = (List) ruleConfig; + if (ruleConfig instanceof List || ruleConfig instanceof Set) { + Collection convertedRuleList = (Collection) ruleConfig; if (CollectionUtils.isEmpty(convertedRuleList)) { log.warn("[Sentinel Starter] DataSource {} rule list is empty.", dataSourceName); 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();