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 2318f321..b1afad56 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 @@ -6,8 +6,6 @@ import java.util.Optional; 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; @@ -46,11 +44,13 @@ public enum RuleType { /** * gateway flow */ - GW_FLOW("gw-flow", GatewayFlowRule.class), + GW_FLOW("gw-flow", + "com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"), /** * api */ - GW_API_GROUP("gw-api-group", ApiDefinition.class); + GW_API_GROUP("gw-api-group", + "com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition"); /** * alias for {@link AbstractRule} @@ -60,19 +60,39 @@ public enum RuleType { /** * concrete {@link AbstractRule} class */ - private final Class clazz; + private Class clazz; + + /** + * concrete {@link AbstractRule} class name + */ + private String clazzName; RuleType(String name, Class clazz) { this.name = name; this.clazz = clazz; } + RuleType(String name, String clazzName) { + this.name = name; + this.clazzName = clazzName; + } + public String getName() { return name; } public Class getClazz() { - return clazz; + if (clazz != null) { + return clazz; + } + else { + try { + return Class.forName(clazzName); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } } public static Optional getByName(String name) { 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 649f8f3b..3037b8c1 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 @@ -12,8 +12,6 @@ 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.authority.AuthorityRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; @@ -57,11 +55,13 @@ public abstract class SentinelConverter Collection ruleCollection; // hard code - if (ruleClass == GatewayFlowRule.class || ruleClass == ApiDefinition.class) { - ruleCollection = new HashSet<>(); + if (ruleClass == FlowRule.class || ruleClass == DegradeRule.class + || ruleClass == SystemRule.class || ruleClass == AuthorityRule.class + || ruleClass == ParamFlowRule.class) { + ruleCollection = new ArrayList<>(); } else { - ruleCollection = new ArrayList<>(); + ruleCollection = new HashSet<>(); } if (StringUtils.isEmpty(source)) { diff --git a/spring-cloud-alibaba-sentinel-gateway/pom.xml b/spring-cloud-alibaba-sentinel-gateway/pom.xml index 7675db8f..498e370b 100644 --- a/spring-cloud-alibaba-sentinel-gateway/pom.xml +++ b/spring-cloud-alibaba-sentinel-gateway/pom.xml @@ -19,6 +19,14 @@ spring-cloud-starter-netflix-zuul true + + com.alibaba.csp + sentinel-api-gateway-adapter-common + + + com.alibaba.csp + sentinel-parameter-flow-control + com.alibaba.csp sentinel-zuul-adapter @@ -27,11 +35,20 @@ com.alibaba.csp sentinel-spring-cloud-gateway-adapter + + org.springframework.cloud + spring-cloud-alibaba-sentinel-datasource + org.springframework.cloud spring-cloud-starter-gateway true + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + provided + org.springframework.boot spring-boot-configuration-processor diff --git a/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/gateway/SentinelGatewayAutoConfiguration.java b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/gateway/SentinelGatewayAutoConfiguration.java new file mode 100644 index 00000000..223ff526 --- /dev/null +++ b/spring-cloud-alibaba-sentinel-gateway/src/main/java/org/springframework/cloud/alibaba/sentinel/gateway/SentinelGatewayAutoConfiguration.java @@ -0,0 +1,161 @@ +/* + * 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.sentinel.gateway; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter; +import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +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.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; + +/** + * @author Jim + */ +@Configuration +@ConditionalOnProperty(name = "spring.cloud.sentinel.enabled", matchIfMissing = true) +public class SentinelGatewayAutoConfiguration { + + @ConditionalOnClass(ObjectMapper.class) + @Configuration + protected static class SentinelConverterConfiguration { + + static class ApiPredicateItemDeserializer + extends StdDeserializer { + private Map> registry = new HashMap>(); + + 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); + } + } + + @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-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); + } + } + + @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-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); + } + + } + } + +} diff --git a/spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories index 15297fce..8917e7c4 100644 --- a/spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-sentinel-gateway/src/main/resources/META-INF/spring.factories @@ -1,3 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.alibaba.sentinel.gateway.zuul.SentinelZuulAutoConfiguration,\ -org.springframework.cloud.alibaba.sentinel.gateway.scg.SentinelSCGAutoConfiguration \ No newline at end of file +org.springframework.cloud.alibaba.sentinel.gateway.scg.SentinelSCGAutoConfiguration,\ +org.springframework.cloud.alibaba.sentinel.gateway.SentinelGatewayAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-alibaba-sentinel/pom.xml b/spring-cloud-alibaba-sentinel/pom.xml index a832136b..77c69e6a 100644 --- a/spring-cloud-alibaba-sentinel/pom.xml +++ b/spring-cloud-alibaba-sentinel/pom.xml @@ -84,6 +84,12 @@ sentinel-parameter-flow-control + + com.alibaba.csp + sentinel-api-gateway-adapter-common + true + + com.alibaba.csp sentinel-cluster-server-default @@ -105,11 +111,6 @@ 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 00f7576e..55bddf6c 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,12 +16,6 @@ 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; @@ -40,11 +34,6 @@ 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.config.WebServletConfig; import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect; import com.alibaba.csp.sentinel.config.SentinelConfig; @@ -58,15 +47,8 @@ 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; /** @@ -170,6 +152,7 @@ public class SentinelAutoConfiguration { } @Bean + @ConditionalOnMissingBean public SentinelDataSourceHandler sentinelDataSourceHandler( DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, Environment env) { @@ -180,41 +163,6 @@ public class SentinelAutoConfiguration { @Configuration protected static class SentinelConverterConfiguration { - static class ApiPredicateItemDeserializer - extends StdDeserializer { - private Map> registry = new HashMap>(); - - 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); - } - } - @Configuration protected static class SentinelJsonConfiguration { @@ -223,17 +171,6 @@ public class SentinelAutoConfiguration { 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") @@ -261,15 +198,6 @@ public class SentinelAutoConfiguration { 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); - } } @ConditionalOnClass(XmlMapper.class) @@ -281,16 +209,6 @@ public class SentinelAutoConfiguration { 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") @@ -318,16 +236,6 @@ public class SentinelAutoConfiguration { 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); - } - } }