diff --git a/pom.xml b/pom.xml index 15b89329..c98e94c1 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,7 @@ spring-cloud-alibaba-dependencies spring-cloud-alibaba-sentinel spring-cloud-alibaba-sentinel-datasource + spring-cloud-alibaba-sentinel-zuul spring-cloud-alibaba-nacos-config spring-cloud-alibaba-nacos-discovery spring-cloud-alibaba-fescar diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml index eb376120..128910ae 100644 --- a/spring-cloud-alibaba-dependencies/pom.xml +++ b/spring-cloud-alibaba-dependencies/pom.xml @@ -134,6 +134,11 @@ sentinel-web-servlet ${sentinel.version} + + com.alibaba.csp + sentinel-zuul-adapter + ${sentinel.version} + com.alibaba.csp sentinel-transport-simple-http diff --git a/spring-cloud-alibaba-sentinel-zuul/pom.xml b/spring-cloud-alibaba-sentinel-zuul/pom.xml new file mode 100644 index 00000000..25946575 --- /dev/null +++ b/spring-cloud-alibaba-sentinel-zuul/pom.xml @@ -0,0 +1,44 @@ + + + + spring-cloud-alibaba + org.springframework.cloud + 0.1.2.BUILD-SNAPSHOT + + 4.0.0 + + org.springframework.cloud + spring-cloud-alibaba-sentinel-zuul + Spring Cloud Alibaba Sentinel Zuul + + + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + provided + + + com.alibaba.csp + sentinel-zuul-adapter + + + org.springframework.boot + spring-boot-configuration-processor + provided + true + + + junit + junit + test + + + org.mockito + mockito-core + test + + + + 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 new file mode 100644 index 00000000..84da3481 --- /dev/null +++ b/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/SentinelZuulAutoConfiguration.java @@ -0,0 +1,114 @@ +/* + * 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.listener.FallBackProviderListener; +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") +public class SentinelZuulAutoConfiguration { + + @Autowired + private Environment environment; + + public static final String PREFIX = "spring.cloud.alibaba.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 FallBackProviderListener fallBackProviderListener( + DefaultListableBeanFactory beanFactory) { + return new FallBackProviderListener(beanFactory); + } + +} \ No newline at end of file diff --git a/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/listener/FallBackProviderListener.java b/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/listener/FallBackProviderListener.java new file mode 100644 index 00000000..31b9cafa --- /dev/null +++ b/spring-cloud-alibaba-sentinel-zuul/src/main/java/org/springframework/cloud/alibaba/sentinel/zuul/listener/FallBackProviderListener.java @@ -0,0 +1,45 @@ +package org.springframework.cloud.alibaba.sentinel.zuul.listener; + +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 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; + +/** + * @author tiger + */ +public class FallBackProviderListener implements SmartInitializingSingleton { + + private static final Logger logger = LoggerFactory + .getLogger(FallBackProviderListener.class); + + private final DefaultListableBeanFactory beanFactory; + + public FallBackProviderListener(DefaultListableBeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public void afterSingletonsInstantiated() { + Map providerMap = beanFactory + .getBeansOfType(ZuulBlockFallbackProvider.class); + if (MapUtils.isNotEmpty(providerMap)) { + for (String k : providerMap.keySet()) { + logger.info("[Sentinel] Register provider name:{}, instance: {}", k, + providerMap.get(k)); + ZuulBlockFallbackManager.registerProvider(providerMap.get(k)); + } + } + else { + logger.info("[Sentinel] Register default fallback provider. "); + ZuulBlockFallbackManager.registerProvider(new DefaultBlockFallbackProvider()); + } + } +} \ No newline at end of file diff --git a/spring-cloud-alibaba-sentinel-zuul/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-sentinel-zuul/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..2304b8a3 --- /dev/null +++ b/spring-cloud-alibaba-sentinel-zuul/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.alibaba.sentinel.zuul.SentinelZuulAutoConfiguration