diff --git a/pom.xml b/pom.xml index 440d0a6c..0089bc22 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ cn.springcloud.gray spring-cloud-gray pom - 2.0.0 + 2.1.0 https://github.com/SpringCloud/spring-cloud-gray Spring Cloud中国社区 diff --git a/spring-cloud-gray-client-netflix/pom.xml b/spring-cloud-gray-client-netflix/pom.xml index 97a17ae4..76b842d0 100644 --- a/spring-cloud-gray-client-netflix/pom.xml +++ b/spring-cloud-gray-client-netflix/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-client-netflix/src/main/java/cn/springcloud/gray/client/netflix/configuration/HystrixGrayAutoConfiguration.java b/spring-cloud-gray-client-netflix/src/main/java/cn/springcloud/gray/client/netflix/configuration/HystrixGrayAutoConfiguration.java index a39727c9..a274db50 100644 --- a/spring-cloud-gray-client-netflix/src/main/java/cn/springcloud/gray/client/netflix/configuration/HystrixGrayAutoConfiguration.java +++ b/spring-cloud-gray-client-netflix/src/main/java/cn/springcloud/gray/client/netflix/configuration/HystrixGrayAutoConfiguration.java @@ -2,9 +2,8 @@ import cn.springcloud.gray.GrayManager; import cn.springcloud.gray.client.netflix.hystrix.HystrixRequestLocalStorage; -import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; import cn.springcloud.gray.request.RequestLocalStorage; +import cn.springcloud.gray.request.track.GrayTrackHolder; import cn.springcloud.gray.web.GrayTrackFilter; import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; @@ -18,9 +17,7 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; -import java.util.List; @Configuration @ConditionalOnClass({HystrixCommand.class, HystrixFeign.class}) @@ -39,9 +36,9 @@ public RequestLocalStorage requestLocalStorage() { @Bean public GrayTrackFilter grayTrackFilter( - RequestLocalStorage requestLocalStorage, - List> trackors) { - return new GrayTrackFilter(requestLocalStorage, trackors) { + GrayTrackHolder grayTrackHolder, + RequestLocalStorage requestLocalStorage) { + return new GrayTrackFilter(grayTrackHolder, requestLocalStorage) { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!HystrixRequestContext.isCurrentThreadInitialized()) { diff --git a/spring-cloud-gray-client/pom.xml b/spring-cloud-gray-client/pom.xml index ad4f1fb1..36445e56 100644 --- a/spring-cloud-gray-client/pom.xml +++ b/spring-cloud-gray-client/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 @@ -56,7 +56,7 @@ cn.springcloud.gray spring-cloud-gray-utils - 2.0.0 + 2.1.0 compile diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/AbstractCommunicableGrayManager.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/AbstractCommunicableGrayManager.java index 15e63bd8..e96d59fb 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/AbstractCommunicableGrayManager.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/AbstractCommunicableGrayManager.java @@ -1,8 +1,6 @@ package cn.springcloud.gray; -import cn.springcloud.gray.communication.HttpInformationClient; import cn.springcloud.gray.communication.InformationClient; -import cn.springcloud.gray.communication.RetryableInformationClient; import cn.springcloud.gray.decision.GrayDecisionFactoryKeeper; import java.util.List; @@ -12,9 +10,12 @@ public abstract class AbstractCommunicableGrayManager extends SimpleGrayManager private GrayClientConfig grayClientConfig; private InformationClient informationClient; - public AbstractCommunicableGrayManager(GrayClientConfig grayClientConfig, GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, List requestInterceptors) { + public AbstractCommunicableGrayManager( + GrayClientConfig grayClientConfig, GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, + List requestInterceptors, InformationClient informationClient) { super(grayDecisionFactoryKeeper, requestInterceptors); this.grayClientConfig = grayClientConfig; + this.informationClient = informationClient; createInformationClient(); } @@ -29,13 +30,6 @@ public InformationClient getGrayInformationClient() { protected void createInformationClient() { - GrayClientConfig clientConfig = getGrayClientConfig(); - InformationClient httpClient = new HttpInformationClient(clientConfig.getServerUrl()); - if (clientConfig.isRetryable()) { - informationClient = new RetryableInformationClient(Math.max(3, clientConfig.getRetryNumberOfRetries()), httpClient); - } else { - informationClient = httpClient; - } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/CommunicableGrayManager.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/CommunicableGrayManager.java index ddab3697..a8d22b46 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/CommunicableGrayManager.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/CommunicableGrayManager.java @@ -1,9 +1,7 @@ package cn.springcloud.gray; -import cn.springcloud.gray.communication.InformationClient; -public interface CommunicableGrayManager extends GrayManager { +public interface CommunicableGrayManager extends GrayManager, GrayServerCommunicable { - InformationClient getGrayInformationClient(); } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/DefaultGrayManager.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/DefaultGrayManager.java index 06ad5e1b..27667ef2 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/DefaultGrayManager.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/DefaultGrayManager.java @@ -1,6 +1,7 @@ package cn.springcloud.gray; - +import cn.springcloud.gray.client.config.properties.GrayLoadProperties; +import cn.springcloud.gray.communication.InformationClient; import cn.springcloud.gray.decision.GrayDecisionFactoryKeeper; import cn.springcloud.gray.model.GrayInstance; import cn.springcloud.gray.model.GrayService; @@ -16,32 +17,43 @@ public class DefaultGrayManager extends AbstractCommunicableGrayManager { private Timer updateTimer = new Timer("Gray-Update-Timer", true); - - public DefaultGrayManager(GrayClientConfig grayClientConfig, GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, - List requestInterceptors) { - super(grayClientConfig, grayDecisionFactoryKeeper, requestInterceptors); + private GrayLoadProperties grayLoadProperties; + + public DefaultGrayManager( + GrayClientConfig grayClientConfig, + GrayLoadProperties grayLoadProperties, + GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, + List requestInterceptors, + InformationClient informationClient) { + super(grayClientConfig, grayDecisionFactoryKeeper, requestInterceptors, informationClient); + this.grayLoadProperties = grayLoadProperties; openForWork(); } - public void openForWork() { log.info("拉取灰度列表"); - doUpdate(); - updateTimer.schedule(new UpdateTask(), - getGrayClientConfig().getServiceUpdateIntervalTimerInMs(), - getGrayClientConfig().getServiceUpdateIntervalTimerInMs()); - } + if (getGrayInformationClient() != null) { + doUpdate(); + int timerMs = getGrayClientConfig().getServiceUpdateIntervalTimerInMs(); + if (timerMs > 0) { + updateTimer.schedule(new UpdateTask(), timerMs, timerMs); + } + } else { + loadPropertiesGrays(); + } + } private void doUpdate() { try { log.debug("更新灰度服务列表..."); - List grayInstances = getGrayInformationClient().allGrayInstances(); Map grayServices = new ConcurrentHashMap<>(); - grayInstances.forEach(instance -> { - updateGrayInstance(grayServices, instance); - }); + grayInstances.forEach( + instance -> { + updateGrayInstance(grayServices, instance); + }); + joinLoadedGrays(grayServices); this.grayServices = grayServices; } catch (Exception e) { log.error("更新灰度服务列表失败", e); @@ -49,6 +61,31 @@ private void doUpdate() { } + private void loadPropertiesGrays() { + Map grayServices = new ConcurrentHashMap<>(); + joinLoadedGrays(grayServices); + this.grayServices = grayServices; + } + + + /** + * 加入配置文件中的灰度实例,但不会覆盖列表中的信息 + * + * @param grayServices 更新的灰度列表 + */ + private void joinLoadedGrays(Map grayServices) { + if (grayLoadProperties != null && grayLoadProperties.isEnabled()) { + grayLoadProperties.getGrayInstances().forEach( + instance -> { + if (grayServices.containsKey(instance.getServiceId()) + || grayServices.get(instance.getServiceId()) + .getGrayInstance(instance.getInstanceId()) != null) { + updateGrayInstance(grayServices, instance); + } + }); + } + } + class UpdateTask extends TimerTask { @Override @@ -56,6 +93,4 @@ public void run() { doUpdate(); } } - - } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayClientConfig.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayClientConfig.java index e11c942b..323a8caf 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayClientConfig.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayClientConfig.java @@ -34,7 +34,7 @@ public interface GrayClientConfig { /** - * 更新灰度列表的时间间隔(ms) + * 更新灰度列表的时间间隔(ms),小于等于0将不会开启定时轮询 * * @return 返回更新灰度列表的时间间隔(ms) */ diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayServerCommunicable.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayServerCommunicable.java new file mode 100644 index 00000000..9d2f1fab --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/GrayServerCommunicable.java @@ -0,0 +1,8 @@ +package cn.springcloud.gray; + +import cn.springcloud.gray.communication.InformationClient; + +public interface GrayServerCommunicable { + + InformationClient getGrayInformationClient(); +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/InstanceLocalInfoAware.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/InstanceLocalInfoAware.java new file mode 100644 index 00000000..1696eed8 --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/InstanceLocalInfoAware.java @@ -0,0 +1,6 @@ +package cn.springcloud.gray; + +public interface InstanceLocalInfoAware { + + void setInstanceLocalInfo(InstanceLocalInfo instanceLocalInfo); +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientAutoConfiguration.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientAutoConfiguration.java index df498074..699193f2 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientAutoConfiguration.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientAutoConfiguration.java @@ -3,13 +3,18 @@ import cn.springcloud.gray.*; import cn.springcloud.gray.client.GrayClientInitializingDestroyBean; import cn.springcloud.gray.client.config.properties.GrayClientProperties; +import cn.springcloud.gray.client.config.properties.GrayLoadProperties; import cn.springcloud.gray.client.config.properties.GrayRequestProperties; +import cn.springcloud.gray.communication.HttpInformationClient; +import cn.springcloud.gray.communication.InformationClient; +import cn.springcloud.gray.communication.RetryableInformationClient; import cn.springcloud.gray.decision.GrayDecisionFactoryKeeper; import cn.springcloud.gray.request.RequestLocalStorage; import cn.springcloud.gray.request.ThreadLocalRequestStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -30,9 +35,27 @@ public class GrayClientAutoConfiguration { @Bean @ConditionalOnMissingBean - public GrayManager grayManager(GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, - @Autowired(required = false) List requestInterceptors) { - return new DefaultGrayManager(grayClientProperties, grayDecisionFactoryKeeper, requestInterceptors); + @ConditionalOnProperty(value = "gray.client.serverUrl") + public InformationClient informationClient() { + InformationClient httpClient = new HttpInformationClient(grayClientProperties.getServerUrl()); + if (grayClientProperties.isRetryable()) { + return new RetryableInformationClient(Math.max(3, grayClientProperties.getRetryNumberOfRetries()), httpClient); + } else { + return httpClient; + } + } + + + @Bean + @ConditionalOnMissingBean + public GrayManager grayManager( + @Autowired(required = false) GrayLoadProperties grayLoadProperties, + GrayDecisionFactoryKeeper grayDecisionFactoryKeeper, + @Autowired(required = false) List requestInterceptors, + InformationClient informationClient) { + return new DefaultGrayManager( + grayClientProperties, grayLoadProperties, grayDecisionFactoryKeeper, + requestInterceptors, informationClient); } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientBeanPostProcessorConfiguration.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientBeanPostProcessorConfiguration.java new file mode 100644 index 00000000..8a643e54 --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayClientBeanPostProcessorConfiguration.java @@ -0,0 +1,35 @@ +package cn.springcloud.gray.client.config; + +import cn.springcloud.gray.InstanceLocalInfo; +import cn.springcloud.gray.InstanceLocalInfoAware; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GrayClientBeanPostProcessorConfiguration { + + + @Bean +// @ConditionalOnBean(InstanceLocalInfo.class) + public BeanPostProcessor beanPostProcessor(InstanceLocalInfo instanceLocalInfo) { + return new BeanPostProcessor() { + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof InstanceLocalInfoAware) { + ((InstanceLocalInfoAware) bean).setInstanceLocalInfo(instanceLocalInfo); + } + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + + + return bean; + } + }; + } + +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayEventAutoConfiguration.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayEventAutoConfiguration.java index b22a63cb..eb141c64 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayEventAutoConfiguration.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayEventAutoConfiguration.java @@ -5,6 +5,7 @@ import cn.springcloud.gray.event.GrayEventListener; import cn.springcloud.gray.event.stream.StreamInput; import cn.springcloud.gray.event.stream.StreamMessageListener; +import cn.springcloud.gray.request.track.CommunicableGrayTrackHolder; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -18,8 +19,9 @@ public class GrayEventAutoConfiguration { @Bean @ConditionalOnMissingBean - public GrayEventListener grayEventListener(CommunicableGrayManager grayManager) { - return new DefaultGrayEventListener(grayManager); + public GrayEventListener grayEventListener( + CommunicableGrayTrackHolder grayTrackHolder, CommunicableGrayManager grayManager) { + return new DefaultGrayEventListener(grayTrackHolder, grayManager); } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayTrackConfiguration.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayTrackConfiguration.java index d2d86046..bd16c3d6 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayTrackConfiguration.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/GrayTrackConfiguration.java @@ -2,13 +2,16 @@ import cn.springcloud.gray.client.config.properties.GrayTrackProperties; +import cn.springcloud.gray.communication.InformationClient; import cn.springcloud.gray.request.GrayHttpTrackInfo; import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.GrayTrackInfo; import cn.springcloud.gray.request.RequestLocalStorage; +import cn.springcloud.gray.request.track.DefaultGrayTrackHolder; +import cn.springcloud.gray.request.track.GrayTrackHolder; import cn.springcloud.gray.web.GrayTrackFilter; import cn.springcloud.gray.web.GrayTrackRequestInterceptor; import cn.springcloud.gray.web.tracker.*; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -16,8 +19,6 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import javax.servlet.http.HttpServletRequest; @@ -29,6 +30,16 @@ public class GrayTrackConfiguration { + @Bean(initMethod = "openForWork") + @ConditionalOnMissingBean + public GrayTrackHolder grayTrackHolder( + GrayTrackProperties grayTrackProperties, + @Autowired(required = false) InformationClient informationClient, + List> trackers) { + return new DefaultGrayTrackHolder(grayTrackProperties, informationClient, trackers); + } + + @ConditionalOnProperty(value = "gray.client.runenv", havingValue = "web", matchIfMissing = true) @Configuration public static class GrayClientWebConfiguration extends WebMvcConfigurerAdapter { @@ -42,29 +53,10 @@ public static class GrayClientWebConfiguration extends WebMvcConfigurerAdapter { @Autowired private RequestLocalStorage requestLocalStorage; -// @Bean -// @ConditionalOnMissingBean -// public GrayTrackInterceptor grayTrackInterceptor() { -// return new GrayTrackInterceptor(requestLocalStorage, trackors); -// } - -// @Override -// public void addInterceptors(InterceptorRegistry registry) { -// InterceptorRegistration grayTrackRegistor = registry.addInterceptor(grayTrackInterceptor()); -// GrayTrackProperties.Web webProperties = grayTrackProperties.getWeb(); -// -// for (String pattern : webProperties.getPathPatterns()) { -// grayTrackRegistor.addPathPatterns(pattern); -// } -// for (String pattern : webProperties.getExcludePathPatterns()) { -// grayTrackRegistor.excludePathPatterns(pattern); -// } -// } - @Bean @ConditionalOnMissingBean - public GrayTrackFilter grayTrackFilter() { - return new GrayTrackFilter(requestLocalStorage, trackors); + public GrayTrackFilter grayTrackFilter(GrayTrackHolder grayTrackHolder) { + return new GrayTrackFilter(grayTrackHolder, requestLocalStorage); } @@ -87,48 +79,39 @@ public FilterRegistrationBean companyUrlFilterRegister(GrayTrackFilter filter) { @Bean - public HttpReceiveGrayTracker httpReceiveGrayTracker() { - return new HttpReceiveGrayTracker(); + public HttpReceiveGrayInfoTracker httpReceiveGrayTracker() { + return new HttpReceiveGrayInfoTracker(); } @Bean - @ConditionalOnProperty(value = "gray.request.track.web.need.headers") - public HttpHeaderGrayTracker httpHeaderGrayTracker() { - String header = grayTrackProperties.getWeb().getNeed().get(GrayTrackProperties.Web.NEED_HEADERS); - String[] headers = StringUtils.isEmpty(header) ? new String[]{} : header.split(","); - return new HttpHeaderGrayTracker(headers); + public HttpHeaderGrayInfoTracker httpHeaderGrayTracker() { + return new HttpHeaderGrayInfoTracker(); } @Bean - @ConditionalOnProperty(value = "gray.request.track.web.need.method", havingValue = "enable") - public HttpMethodGrayTracker httpMethodGrayTracker() { - return new HttpMethodGrayTracker(); + public HttpMethodGrayInfoTracker httpMethodGrayTracker() { + return new HttpMethodGrayInfoTracker(); } @Bean - @ConditionalOnProperty(value = "gray.request.track.web.need.uri", havingValue = "enable") - public HttpURIGrayTracker httpURIGrayTracker() { - return new HttpURIGrayTracker(); + public HttpURIGrayInfoTracker httpURIGrayTracker() { + return new HttpURIGrayInfoTracker(); } @Bean - @ConditionalOnProperty(value = "gray.request.track.web.need.ip", havingValue = "enable") - public HttpIPGrayTracker httpIPGrayTracker() { - return new HttpIPGrayTracker(); + public HttpIPGrayInfoTracker httpIPGrayTracker() { + return new HttpIPGrayInfoTracker(); } @Bean - @ConditionalOnProperty(value = "gray.request.track.web.need.parameters", havingValue = "enable") - public HttpParameterGrayTracker httpParameterGrayTracker() { - String name = grayTrackProperties.getWeb().getNeed().get(GrayTrackProperties.Web.NEED_PARAMETERS); - String[] names = StringUtils.isEmpty(name) ? new String[]{} : name.split(","); - return new HttpParameterGrayTracker(names); + public HttpParameterGrayInfoTracker httpParameterGrayTracker() { + return new HttpParameterGrayInfoTracker(); } @Bean public GrayTrackRequestInterceptor grayTrackRequestInterceptor() { - return new GrayTrackRequestInterceptor(grayTrackProperties); + return new GrayTrackRequestInterceptor(); } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayClientProperties.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayClientProperties.java index 18f1fc16..139835e7 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayClientProperties.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayClientProperties.java @@ -13,7 +13,7 @@ public class GrayClientProperties implements GrayClientConfig { private String informationClient = "http"; - private String serverUrl = "http://localhost:10202"; + private String serverUrl = ""; private boolean retryable = true; private int retryNumberOfRetries = RetryableInformationClient.DEFAULT_NUMBER_OF_RETRIES; diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayTrackProperties.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayTrackProperties.java index cadad69b..8e479f9b 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayTrackProperties.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/client/config/properties/GrayTrackProperties.java @@ -1,11 +1,12 @@ package cn.springcloud.gray.client.config.properties; +import cn.springcloud.gray.model.GrayTrackDefinition; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; @Setter @@ -16,6 +17,8 @@ public class GrayTrackProperties { private String trackType = "web"; private Web web = new Web(); + private int definitionsUpdateIntervalTimerInMs = 0; + @Setter @Getter public static class Web { @@ -29,7 +32,8 @@ public static class Web { private String[] pathPatterns = new String[]{"/*"}; private String[] excludePathPatterns = new String[]{}; - private Map need = new HashMap<>(); + private List trackDefinitions = new ArrayList<>(); + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/HttpInformationClient.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/HttpInformationClient.java index 4d1cd12d..68557cba 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/HttpInformationClient.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/HttpInformationClient.java @@ -1,6 +1,7 @@ package cn.springcloud.gray.communication; import cn.springcloud.gray.model.GrayInstance; +import cn.springcloud.gray.model.GrayTrackDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.ParameterizedTypeReference; @@ -78,4 +79,19 @@ public void serviceDownline(String instanceId) { throw e; } } + + @Override + public List getTrackDefinitions(String serviceId, String instanceId) { + String url = this.baseUrl + "/gray/trackDefinitions?serviceId={serviceId}&instanceId={instanceId}"; + ParameterizedTypeReference> typeRef = new ParameterizedTypeReference>() { + }; + try { + ResponseEntity> responseEntity = + rest.exchange(url, HttpMethod.GET, null, typeRef, serviceId, instanceId); + return responseEntity.getBody(); + } catch (RuntimeException e) { + log.error("获取灰度追踪信息", e); + throw e; + } + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClient.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClient.java index 0168b5df..6fe2c2cb 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClient.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClient.java @@ -1,6 +1,7 @@ package cn.springcloud.gray.communication; import cn.springcloud.gray.model.GrayInstance; +import cn.springcloud.gray.model.GrayTrackDefinition; import java.util.List; @@ -43,4 +44,5 @@ public interface InformationClient { */ void serviceDownline(String instanceId); + List getTrackDefinitions(String serviceId, String instanceId); } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClientDecorator.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClientDecorator.java index 4e8e8992..0a011e90 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClientDecorator.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/communication/InformationClientDecorator.java @@ -1,6 +1,7 @@ package cn.springcloud.gray.communication; import cn.springcloud.gray.model.GrayInstance; +import cn.springcloud.gray.model.GrayTrackDefinition; import java.util.List; @@ -12,10 +13,11 @@ public abstract class InformationClientDecorator implements InformationClient { public enum RequestType { - AddGrayInstance, - ServiceDownline, - AllGrayInstances, - GetGrayInstance + ADD_GRAY_INSTANCE, + SERVICE_DOWNLINE, + ALL_GRAY_INSTANCES, + GET_GRAY_INSTANCE, + GET_TRACK_DEFINITIONS, } @@ -38,7 +40,7 @@ public GrayInstance execute(InformationClient delegate) { @Override public RequestType getRequestType() { - return RequestType.GetGrayInstance; + return RequestType.GET_GRAY_INSTANCE; } }); } @@ -53,7 +55,7 @@ public List execute(InformationClient delegate) { @Override public RequestType getRequestType() { - return RequestType.AllGrayInstances; + return RequestType.ALL_GRAY_INSTANCES; } }); } @@ -71,7 +73,7 @@ public Object execute(InformationClient delegate) { @Override public RequestType getRequestType() { - return RequestType.AddGrayInstance; + return RequestType.ADD_GRAY_INSTANCE; } }); } @@ -88,7 +90,22 @@ public Object execute(InformationClient delegate) { @Override public RequestType getRequestType() { - return RequestType.ServiceDownline; + return RequestType.SERVICE_DOWNLINE; + } + }); + } + + @Override + public List getTrackDefinitions(String serviceId, String instanceId) { + return execute(new RequestExecutor>() { + @Override + public List execute(InformationClient delegate) { + return delegate.getTrackDefinitions(serviceId, instanceId); + } + + @Override + public RequestType getRequestType() { + return RequestType.GET_TRACK_DEFINITIONS; } }); } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/decision/factory/GrayDecisionFactory.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/decision/factory/GrayDecisionFactory.java index aa5602fb..2a01bfe6 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/decision/factory/GrayDecisionFactory.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/decision/factory/GrayDecisionFactory.java @@ -1,9 +1,7 @@ package cn.springcloud.gray.decision.factory; import cn.springcloud.gray.decision.GrayDecision; -import cn.springcloud.gray.model.DecisionDefinition; import cn.springcloud.gray.utils.NameUtils; -import org.springframework.beans.BeanUtils; import java.util.function.Consumer; @@ -14,7 +12,7 @@ public interface GrayDecisionFactory { default String name() { - return NameUtils.normalizeFilterFactoryName(getClass()); + return NameUtils.normalizeDecisionFactoryName(getClass()); } default C newConfig() { diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/event/DefaultGrayEventListener.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/event/DefaultGrayEventListener.java index 68d06421..171324f7 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/event/DefaultGrayEventListener.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/event/DefaultGrayEventListener.java @@ -1,19 +1,63 @@ package cn.springcloud.gray.event; import cn.springcloud.gray.CommunicableGrayManager; +import cn.springcloud.gray.InstanceLocalInfo; +import cn.springcloud.gray.InstanceLocalInfoAware; import cn.springcloud.gray.exceptions.EventException; import cn.springcloud.gray.model.GrayInstance; +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.request.track.CommunicableGrayTrackHolder; +import org.apache.commons.lang3.StringUtils; -public class DefaultGrayEventListener implements GrayEventListener { +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +public class DefaultGrayEventListener implements GrayEventListener, InstanceLocalInfoAware { private CommunicableGrayManager grayManager; + private CommunicableGrayTrackHolder grayTrackHolder; + private InstanceLocalInfo instanceLocalInfo; + + private Map> handers = new HashMap<>(); - public DefaultGrayEventListener(CommunicableGrayManager grayManager) { + public DefaultGrayEventListener(CommunicableGrayTrackHolder grayTrackHolder, CommunicableGrayManager grayManager) { this.grayManager = grayManager; + initHandlers(); + this.grayTrackHolder = grayTrackHolder; } @Override public void onEvent(GrayEventMsg msg) throws EventException { + handleSource(msg); + } + + private void handleSource(GrayEventMsg msg) { + Optional.ofNullable(getHandler(msg.getSourceType())).ifPresent(handler -> { + handler.accept(msg); + }); + } + + + private Consumer getHandler(SourceType type) { + return handers.get(type); + } + + + private void initHandlers() { + putHandler(SourceType.GRAY_INSTANCE, this::handleGrayInstance) + .putHandler(SourceType.GRAY_TRACK, this::handleGrayTrack); + } + + private DefaultGrayEventListener putHandler(SourceType sourceType, Consumer handler) { + handers.put(sourceType, handler); + return this; + } + + + private void handleGrayInstance(GrayEventMsg msg) { switch (msg.getEventType()) { case DOWN: grayManager.closeGray(msg.getServiceId(), msg.getInstanceId()); @@ -23,4 +67,39 @@ public void onEvent(GrayEventMsg msg) throws EventException { grayManager.updateGrayInstance(grayInstance); } } + + private void handleGrayTrack(GrayEventMsg msg) { + if (!StringUtils.equals(msg.getServiceId(), instanceLocalInfo.getServiceId())) { + return; + } + if (StringUtils.isNotEmpty(msg.getInstanceId()) + && !StringUtils.equals(msg.getInstanceId(), instanceLocalInfo.getInstanceId())) { + return; + } + + GrayTrackDefinition definition = (GrayTrackDefinition) msg.getExtra(); + if (definition == null) { + List definitions = + grayTrackHolder.getGrayInformationClient().getTrackDefinitions(msg.getServiceId(), msg.getInstanceId()); + if (definitions != null) { + definitions.forEach(d -> { + grayTrackHolder.updateTrackDefinition(d); + }); + } + } else { + switch (msg.getEventType()) { + case DOWN: + grayTrackHolder.deleteTrackDefinition(definition.getName()); + case UPDATE: + grayTrackHolder.updateTrackDefinition(definition); + } + } + + + } + + @Override + public void setInstanceLocalInfo(InstanceLocalInfo instanceLocalInfo) { + this.instanceLocalInfo = instanceLocalInfo; + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/GrayInfoTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/GrayInfoTracker.java index adae8aec..087b3d1a 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/GrayInfoTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/GrayInfoTracker.java @@ -1,16 +1,22 @@ package cn.springcloud.gray.request; +import cn.springcloud.gray.utils.NameUtils; import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; public interface GrayInfoTracker extends Ordered { - void call(TRACK trackInfo, REQ request); + void call(TrackArgs args); + @Override default int getOrder() { return Ordered.LOWEST_PRECEDENCE; } + default String name() { + return NameUtils.normalizeName(getClass(), GrayInfoTracker.class); + } + + ; } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/TrackArgs.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/TrackArgs.java new file mode 100644 index 00000000..4c2d433f --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/TrackArgs.java @@ -0,0 +1,17 @@ +package cn.springcloud.gray.request; + +import cn.springcloud.gray.model.GrayTrackDefinition; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class TrackArgs { + + private TRACK trackInfo; + private REQ request; + private GrayTrackDefinition trackDefinition; + +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/AbstractCommunicableGrayTrackHolder.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/AbstractCommunicableGrayTrackHolder.java new file mode 100644 index 00000000..8bf8b7c7 --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/AbstractCommunicableGrayTrackHolder.java @@ -0,0 +1,27 @@ +package cn.springcloud.gray.request.track; + +import cn.springcloud.gray.communication.InformationClient; +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.GrayTrackInfo; + +import java.util.List; + +public abstract class AbstractCommunicableGrayTrackHolder extends SimpleGrayTrackHolder implements CommunicableGrayTrackHolder { + + + private InformationClient informationClient; + + public AbstractCommunicableGrayTrackHolder( + InformationClient informationClient, + List> trackers, + List trackDefinitions) { + super(trackers, trackDefinitions); + this.informationClient = informationClient; + } + + @Override + public InformationClient getGrayInformationClient() { + return informationClient; + } +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/CommunicableGrayTrackHolder.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/CommunicableGrayTrackHolder.java new file mode 100644 index 00000000..a4cefbef --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/CommunicableGrayTrackHolder.java @@ -0,0 +1,6 @@ +package cn.springcloud.gray.request.track; + +import cn.springcloud.gray.GrayServerCommunicable; + +public interface CommunicableGrayTrackHolder extends GrayServerCommunicable, GrayTrackHolder { +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/DefaultGrayTrackHolder.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/DefaultGrayTrackHolder.java new file mode 100644 index 00000000..432e703f --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/DefaultGrayTrackHolder.java @@ -0,0 +1,107 @@ +package cn.springcloud.gray.request.track; + +import cn.springcloud.gray.InstanceLocalInfo; +import cn.springcloud.gray.InstanceLocalInfoAware; +import cn.springcloud.gray.client.config.properties.GrayTrackProperties; +import cn.springcloud.gray.communication.InformationClient; +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.GrayTrackInfo; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class DefaultGrayTrackHolder extends AbstractCommunicableGrayTrackHolder implements InstanceLocalInfoAware { + + private Timer updateTimer = new Timer("Gray-Track-Update-Timer", true); + private GrayTrackProperties grayTrackProperties; + private InstanceLocalInfo instanceLocalInfo; + + + public DefaultGrayTrackHolder( + GrayTrackProperties grayTrackProperties, InformationClient informationClient, + List> trackers) { + this(grayTrackProperties, informationClient, trackers, null); + } + + public DefaultGrayTrackHolder( + GrayTrackProperties grayTrackProperties, InformationClient informationClient, + List> trackers, + List trackDefinitions) { + super(informationClient, trackers, trackDefinitions); + this.grayTrackProperties = grayTrackProperties; +// openForWork(); + } + + + public void openForWork() { + log.info("拉取灰度追踪列表"); + + if (getGrayInformationClient() != null) { + doUpdate(); + int timerMs = grayTrackProperties.getDefinitionsUpdateIntervalTimerInMs(); + if (timerMs > 0) { + updateTimer.schedule(new DefaultGrayTrackHolder.UpdateTask(), timerMs, timerMs); + } + } else { + loadPropertiesTrackDefinitions(); + } + } + + private void doUpdate() { + Map trackDefinitionMap = new ConcurrentHashMap<>(); + try { + log.debug("更新灰度追踪列表..."); + + InstanceLocalInfo instanceLocalInfo = getInstanceLocalInfo(); + List trackDefinitions = getGrayInformationClient() + .getTrackDefinitions(instanceLocalInfo.getServiceId(), instanceLocalInfo.getInstanceId()); + trackDefinitions.forEach(definition -> { + updateTrackDefinition(trackDefinitionMap, definition); + }); + } catch (Exception e) { + log.error("更新灰度追踪列表失败", e); + } + joinLoadedTrackDefinitions(trackDefinitionMap); + setTrackDefinitions(trackDefinitionMap); + } + + private void loadPropertiesTrackDefinitions() { + Map trackDefinitionMap = new ConcurrentHashMap<>(); + joinLoadedTrackDefinitions(trackDefinitionMap); + setTrackDefinitions(trackDefinitionMap); + } + + + private void joinLoadedTrackDefinitions(Map definitionMap) { + grayTrackProperties.getWeb().getTrackDefinitions().forEach(definition -> { + if (!definitionMap.containsKey(definition.getName())) { + updateTrackDefinition(definitionMap, definition); + } + }); + } + + @Override + public void setInstanceLocalInfo(InstanceLocalInfo instanceLocalInfo) { + this.instanceLocalInfo = instanceLocalInfo; + } + + public InstanceLocalInfo getInstanceLocalInfo() { + return instanceLocalInfo; + } + + class UpdateTask extends TimerTask { + + @Override + public void run() { + doUpdate(); + } + } + + +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/GrayTrackHolder.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/GrayTrackHolder.java new file mode 100644 index 00000000..f62291a7 --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/GrayTrackHolder.java @@ -0,0 +1,45 @@ +package cn.springcloud.gray.request.track; + +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.GrayTrackInfo; +import cn.springcloud.gray.request.TrackArgs; +import cn.springcloud.gray.utils.LogUtils; + +import java.util.Collection; +import java.util.List; + +public interface GrayTrackHolder { + + + List getGrayInfoTrackers(); + + + Collection getTrackDefinitions(); + + GrayTrackDefinition getGrayTrackDefinition(String name); + + void updateTrackDefinition(GrayTrackDefinition definition); + + void deleteTrackDefinition(String name); + + + default void recordGrayTrack(GrayTrackInfo info, REQ req) { + getGrayInfoTrackers().forEach(tracker -> { + GrayTrackDefinition definition = getGrayTrackDefinition(tracker.name()); + if (definition != null) { + try { + TrackArgs args = TrackArgs.builder() + .trackInfo(info) + .request(req) + .trackDefinition(definition) + .build(); + tracker.call(args); + } catch (Exception e) { + LogUtils.logger(GrayTrackHolder.class).error(e.getMessage()); + } + } + }); + } + +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/SimpleGrayTrackHolder.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/SimpleGrayTrackHolder.java new file mode 100644 index 00000000..7aae0298 --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/request/track/SimpleGrayTrackHolder.java @@ -0,0 +1,75 @@ +package cn.springcloud.gray.request.track; + +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.GrayTrackInfo; +import org.springframework.core.OrderComparator; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class SimpleGrayTrackHolder implements GrayTrackHolder { + + private List> trackers = new ArrayList<>(); + + private Map trackDefinitions = new ConcurrentHashMap<>(); + + + public SimpleGrayTrackHolder(List> trackers, List trackDefinitions) { + initGrayInfoTrackers(trackers); + initGrayTrackDefinitions(trackDefinitions); + } + + private void initGrayTrackDefinitions(Collection trackDefinitions) { + if (trackDefinitions != null) { + trackDefinitions.forEach(definition -> { + if (!this.trackDefinitions.containsKey(definition.getName())) { + this.trackDefinitions.put(definition.getName(), definition); + } + }); + } + } + + private void initGrayInfoTrackers(List> trackers) { + if (trackers == null) { + return; + } + OrderComparator.sort(trackers); + this.trackers = trackers; + } + + + @Override + public List getGrayInfoTrackers() { + return Collections.unmodifiableList(trackers); + } + + @Override + public Collection getTrackDefinitions() { + return trackDefinitions.values(); + } + + @Override + public GrayTrackDefinition getGrayTrackDefinition(String name) { + return trackDefinitions.get(name); + } + + @Override + public void updateTrackDefinition(GrayTrackDefinition definition) { + updateTrackDefinition(trackDefinitions, definition); + } + + protected void updateTrackDefinition(Map trackDefinitions, GrayTrackDefinition definition) { + trackDefinitions.put(definition.getName(), definition); + } + + @Override + public void deleteTrackDefinition(String name) { + trackDefinitions.remove(name); + } + + + protected void setTrackDefinitions(Map trackDefinitions) { + this.trackDefinitions = trackDefinitions; + } +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/LogUtils.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/LogUtils.java new file mode 100644 index 00000000..92a6372f --- /dev/null +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/LogUtils.java @@ -0,0 +1,11 @@ +package cn.springcloud.gray.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogUtils { + + public static Logger logger(Class cls) { + return LoggerFactory.getLogger(cls); + } +} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/NameUtils.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/NameUtils.java index b6f7a318..5e196d0b 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/NameUtils.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/utils/NameUtils.java @@ -19,12 +19,18 @@ public static String generateName(int i) { } - public static String normalizeFilterFactoryName( + public static String normalizeDecisionFactoryName( Class clazz) { return removeGarbage(clazz.getSimpleName() .replace(GrayDecisionFactory.class.getSimpleName(), "")); } + public static String normalizeName( + Class clazz, Class cls) { + return removeGarbage(clazz.getSimpleName() + .replace(cls.getSimpleName(), "")); + } + private static String removeGarbage(String s) { int garbageIdx = s.indexOf("$Mockito"); if (garbageIdx > 0) { diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackFilter.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackFilter.java index 931dc1cc..957528d2 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackFilter.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackFilter.java @@ -1,24 +1,22 @@ package cn.springcloud.gray.web; import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; import cn.springcloud.gray.request.RequestLocalStorage; +import cn.springcloud.gray.request.track.GrayTrackHolder; import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; -import java.util.List; public class GrayTrackFilter implements Filter { private RequestLocalStorage requestLocalStorage; - private List> trackors; + private GrayTrackHolder grayTrackHolder; - public GrayTrackFilter(RequestLocalStorage requestLocalStorage, List> trackors) { + public GrayTrackFilter(GrayTrackHolder grayTrackHolder, RequestLocalStorage requestLocalStorage) { + this.grayTrackHolder = grayTrackHolder; this.requestLocalStorage = requestLocalStorage; - this.trackors = trackors; } @Override @@ -29,7 +27,8 @@ public void init(FilterConfig filterConfig) throws ServletException { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { GrayHttpTrackInfo webTrack = new GrayHttpTrackInfo(); - trackors.forEach(trackor -> trackor.call(webTrack, (HttpServletRequest) request)); +// trackors.forEach(trackor -> trackor.call(webTrack, (HttpServletRequest) request)); + grayTrackHolder.recordGrayTrack(webTrack, request); requestLocalStorage.setGrayTrackInfo(webTrack); try { chain.doFilter(request, response); diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackRequestInterceptor.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackRequestInterceptor.java index 698ee069..63bb5cb6 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackRequestInterceptor.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/GrayTrackRequestInterceptor.java @@ -1,24 +1,24 @@ package cn.springcloud.gray.web; import cn.springcloud.gray.RequestInterceptor; -import cn.springcloud.gray.client.config.properties.GrayTrackProperties; import cn.springcloud.gray.request.GrayHttpRequest; import cn.springcloud.gray.request.GrayHttpTrackInfo; import cn.springcloud.gray.request.GrayRequest; import cn.springcloud.gray.request.GrayTrackInfo; import org.apache.commons.lang3.StringUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.function.Consumer; public class GrayTrackRequestInterceptor implements RequestInterceptor { - private GrayTrackProperties grayTrackProperties; - private Map> handlers = new HashMap<>(); + private List> handlers = new ArrayList<>(); - public GrayTrackRequestInterceptor(GrayTrackProperties grayTrackProperties) { - this.grayTrackProperties = grayTrackProperties; + public GrayTrackRequestInterceptor() { initHandlers(); } @@ -34,9 +34,13 @@ public boolean shouldIntercept() { @Override public boolean pre(GrayRequest request) { - grayTrackProperties.getWeb().getNeed().keySet().forEach(k -> { - Optional.ofNullable(handlers.get(k)).ifPresent(h -> h.accept((GrayHttpRequest) request)); - }); + GrayHttpRequest grayHttpRequest = (GrayHttpRequest) request; + GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); + if (grayHttpTrackInfo != null) { + handlers.forEach(h -> { + h.accept(grayHttpRequest); + }); + } return true; } @@ -51,7 +55,7 @@ public int getOrder() { } private void initHandlers() { - handlers.put(GrayTrackProperties.Web.NEED_IP, request -> { + handlers.add(request -> { GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); if (StringUtils.isNotEmpty(grayHttpTrackInfo.getTraceIp())) { Map> h = (Map>) request.getHeaders(); @@ -59,7 +63,7 @@ private void initHandlers() { } }); - handlers.put(GrayTrackProperties.Web.NEED_URI, request -> { + handlers.add(request -> { GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); if (StringUtils.isNotEmpty(grayHttpTrackInfo.getUri())) { Map> h = (Map>) request.getHeaders(); @@ -68,7 +72,7 @@ private void initHandlers() { }); - handlers.put(GrayTrackProperties.Web.NEED_METHOD, request -> { + handlers.add(request -> { GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); if (StringUtils.isNotEmpty(grayHttpTrackInfo.getUri())) { Map> h = (Map>) request.getHeaders(); @@ -76,7 +80,7 @@ private void initHandlers() { } }); - handlers.put(GrayTrackProperties.Web.NEED_HEADERS, request -> { + handlers.add(request -> { GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); if (StringUtils.isNotEmpty(grayHttpTrackInfo.getUri())) { Map> h = (Map>) request.getHeaders(); @@ -89,7 +93,7 @@ private void initHandlers() { } }); - handlers.put(GrayTrackProperties.Web.NEED_PARAMETERS, request -> { + handlers.add(request -> { GrayHttpTrackInfo grayHttpTrackInfo = (GrayHttpTrackInfo) request.getGrayTrackInfo(); if (StringUtils.isNotEmpty(grayHttpTrackInfo.getUri())) { Map> h = (Map>) request.getHeaders(); diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/interceptor/GrayTrackInterceptor.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/interceptor/GrayTrackInterceptor.java deleted file mode 100644 index 0268f117..00000000 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/interceptor/GrayTrackInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.springcloud.gray.web.interceptor; - -import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; -import cn.springcloud.gray.request.RequestLocalStorage; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.List; - -/** {@link cn.springcloud.gray.web.GrayTrackFilter} */ -public class GrayTrackInterceptor extends HandlerInterceptorAdapter { - - private RequestLocalStorage requestLocalStorage; - - private List> trackors; - - public GrayTrackInterceptor( - RequestLocalStorage requestLocalStorage, - List> trackors) { - this.trackors = trackors; - this.requestLocalStorage = requestLocalStorage; - } - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - GrayHttpTrackInfo webTrack = new GrayHttpTrackInfo(); - trackors.forEach(trackor -> trackor.call(webTrack, request)); - requestLocalStorage.setGrayTrackInfo(webTrack); - return super.preHandle(request, response, handler); - } - - @Override - public void afterCompletion( - HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { - requestLocalStorage.removeGrayTrackInfo(); - super.afterCompletion(request, response, handler, ex); - } -} diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayInfoTracker.java similarity index 66% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayInfoTracker.java index 662cfd6e..cb8fe397 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpGrayInfoTracker.java @@ -5,5 +5,5 @@ import javax.servlet.http.HttpServletRequest; -public interface HttpGrayTracker extends GrayInfoTracker { +public interface HttpGrayInfoTracker extends GrayInfoTracker { } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayInfoTracker.java similarity index 51% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayInfoTracker.java index 6e6c1a9a..fae0041c 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpHeaderGrayInfoTracker.java @@ -1,24 +1,27 @@ package cn.springcloud.gray.web.tracker; import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.TrackArgs; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; @Slf4j -public class HttpHeaderGrayTracker implements HttpGrayTracker { +public class HttpHeaderGrayInfoTracker implements HttpGrayInfoTracker { - private String[] headers; - - public HttpHeaderGrayTracker(String[] headers) { - this.headers = headers; - } @Override - public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { - for (String header : headers) { + public void call(TrackArgs args) { + GrayHttpTrackInfo trackInfo = args.getTrackInfo(); + HttpServletRequest request = args.getRequest(); + String defValue = args.getTrackDefinition().getValue(); + if (StringUtils.isEmpty(defValue)) { + return; + } + + for (String header : defValue.split(",")) { Enumeration headerValues = request.getHeaders(header); while (headerValues.hasMoreElements()) { String value = headerValues.nextElement(); diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayInfoTracker.java similarity index 64% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayInfoTracker.java index 52405b53..0cd0ce2f 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpIPGrayInfoTracker.java @@ -1,21 +1,23 @@ package cn.springcloud.gray.web.tracker; import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.TrackArgs; import cn.springcloud.gray.utils.WebUtils; import lombok.extern.slf4j.Slf4j; import javax.servlet.http.HttpServletRequest; -import java.lang.annotation.Annotation; -import java.util.Enumeration; @Slf4j -public class HttpIPGrayTracker implements HttpGrayTracker { +public class HttpIPGrayInfoTracker implements HttpGrayInfoTracker { - @Override public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { trackInfo.setTraceIp(WebUtils.getIpAddr(request)); log.debug("记录下ip:{}", trackInfo.getTraceIp()); } + + @Override + public void call(TrackArgs args) { + call(args.getTrackInfo(), args.getRequest()); + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayInfoTracker.java similarity index 60% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayInfoTracker.java index f79e129a..f7cef63d 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpMethodGrayInfoTracker.java @@ -1,20 +1,21 @@ package cn.springcloud.gray.web.tracker; import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.TrackArgs; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.http.HttpMethod; import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; @Slf4j -public class HttpMethodGrayTracker implements HttpGrayTracker { +public class HttpMethodGrayInfoTracker implements HttpGrayInfoTracker { - @Override public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { trackInfo.setMethod(request.getMethod()); log.debug("记录下方法:{}", request.getMethod()); } + + @Override + public void call(TrackArgs args) { + call(args.getTrackInfo(), args.getRequest()); + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayInfoTracker.java similarity index 50% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayInfoTracker.java index fe944ac4..c6bc58ff 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpParameterGrayInfoTracker.java @@ -1,31 +1,33 @@ package cn.springcloud.gray.web.tracker; import cn.springcloud.gray.request.GrayHttpTrackInfo; -import cn.springcloud.gray.request.GrayInfoTracker; +import cn.springcloud.gray.request.TrackArgs; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; +import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; -import java.util.Enumeration; @Slf4j -public class HttpParameterGrayTracker implements HttpGrayTracker { +public class HttpParameterGrayInfoTracker implements HttpGrayInfoTracker { - private String[] names; - - public HttpParameterGrayTracker(String[] names) { - this.names = names; - } @Override - public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { - for (String name : names) { + public void call(TrackArgs args) { + GrayHttpTrackInfo trackInfo = args.getTrackInfo(); + HttpServletRequest request = args.getRequest(); + String defValue = args.getTrackDefinition().getValue(); + if (StringUtils.isEmpty(defValue)) { + return; + } + for (String name : defValue.split(",")) { String[] values = request.getParameterValues(name); if (ArrayUtils.isNotEmpty(values)) { trackInfo.setParameters(name, Arrays.asList(values)); log.debug("记录下parameter:{} -> {}", name, values); } } + } } diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayInfoTracker.java similarity index 92% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayInfoTracker.java index e3cfb1a5..02fda76f 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpReceiveGrayInfoTracker.java @@ -2,6 +2,7 @@ import cn.springcloud.gray.request.GrayHttpTrackInfo; import cn.springcloud.gray.request.GrayTrackInfo; +import cn.springcloud.gray.request.TrackArgs; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -11,18 +12,17 @@ import java.util.function.Consumer; @Slf4j -public class HttpReceiveGrayTracker implements HttpGrayTracker { +public class HttpReceiveGrayInfoTracker implements HttpGrayInfoTracker { private Map> loaders = new HashMap<>(); - public HttpReceiveGrayTracker() { + public HttpReceiveGrayInfoTracker() { init(); } - @Override public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { Enumeration headerNames = request.getHeaderNames(); if (headerNames.hasMoreElements()) { @@ -35,6 +35,11 @@ public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { } + @Override + public void call(TrackArgs args) { + call(args.getTrackInfo(), args.getRequest()); + } + @Override public int getOrder() { return 100; diff --git a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayTracker.java b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayInfoTracker.java similarity index 60% rename from spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayTracker.java rename to spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayInfoTracker.java index 50b3f545..23cc1143 100644 --- a/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayTracker.java +++ b/spring-cloud-gray-client/src/main/java/cn/springcloud/gray/web/tracker/HttpURIGrayInfoTracker.java @@ -1,17 +1,23 @@ package cn.springcloud.gray.web.tracker; import cn.springcloud.gray.request.GrayHttpTrackInfo; +import cn.springcloud.gray.request.TrackArgs; import lombok.extern.slf4j.Slf4j; import javax.servlet.http.HttpServletRequest; @Slf4j -public class HttpURIGrayTracker implements HttpGrayTracker { +public class HttpURIGrayInfoTracker implements HttpGrayInfoTracker { - @Override public void call(GrayHttpTrackInfo trackInfo, HttpServletRequest request) { trackInfo.setUri(request.getRequestURI()); log.debug("记录下uri:{}", trackInfo.getUri()); } + + + @Override + public void call(TrackArgs args) { + call(args.getTrackInfo(), args.getRequest()); + } } diff --git a/spring-cloud-gray-core/pom.xml b/spring-cloud-gray-core/pom.xml index fe6e7846..47833ceb 100644 --- a/spring-cloud-gray-core/pom.xml +++ b/spring-cloud-gray-core/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/GrayEventMsg.java b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/GrayEventMsg.java index 6bce2c9b..095f9274 100644 --- a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/GrayEventMsg.java +++ b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/GrayEventMsg.java @@ -14,5 +14,8 @@ public class GrayEventMsg implements Serializable { private String serviceId; private String instanceId; private EventType eventType; + private SourceType sourceType; + + private Object extra; } diff --git a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/SourceType.java b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/SourceType.java new file mode 100644 index 00000000..af7e0890 --- /dev/null +++ b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/event/SourceType.java @@ -0,0 +1,5 @@ +package cn.springcloud.gray.event; + +public enum SourceType { + GRAY_INSTANCE, GRAY_TRACK +} diff --git a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayInstance.java b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayInstance.java index c34e80c7..790bea6d 100644 --- a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayInstance.java +++ b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayInstance.java @@ -15,6 +15,7 @@ @Getter public class GrayInstance implements Serializable { + private static final long serialVersionUID = 1604426811546120884L; private String serviceId; private String instanceId; private String host; @@ -32,4 +33,5 @@ public boolean isGray() { return grayStatus == GrayStatus.OPEN; } + } diff --git a/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayTrackDefinition.java b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayTrackDefinition.java new file mode 100644 index 00000000..6de3efc9 --- /dev/null +++ b/spring-cloud-gray-core/src/main/java/cn/springcloud/gray/model/GrayTrackDefinition.java @@ -0,0 +1,14 @@ +package cn.springcloud.gray.model; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class GrayTrackDefinition { + + + private String name; + + private String value; +} diff --git a/spring-cloud-gray-dependencies/pom.xml b/spring-cloud-gray-dependencies/pom.xml index 3cd8ee9e..24f2b676 100644 --- a/spring-cloud-gray-dependencies/pom.xml +++ b/spring-cloud-gray-dependencies/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 @@ -17,7 +17,7 @@ cn.springcloud.gray spring-cloud-gray-dependencies - 2.0.0 + 2.1.0 pom diff --git a/spring-cloud-gray-samples/pom.xml b/spring-cloud-gray-samples/pom.xml index d08eb884..63664fdf 100644 --- a/spring-cloud-gray-samples/pom.xml +++ b/spring-cloud-gray-samples/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-eureka-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-eureka-sample/pom.xml index 440854a0..b4efe0c8 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-eureka-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-eureka-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 @@ -20,7 +20,7 @@ spring-cloud-gray-utils cn.springcloud.gray - 2.0.0 + 2.1.0 org.springframework.boot diff --git a/spring-cloud-gray-samples/spring-cloud-gray-server-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/pom.xml index 44d03fe3..f02f4881 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-server-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/resources/config/application.yml b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/resources/config/application.yml index 8b772327..bb4b3cdf 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/resources/config/application.yml +++ b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/main/resources/config/application.yml @@ -19,7 +19,7 @@ spring: show-sql: true generate-ddl: true hibernate: - ddl-auto: none + ddl-auto: update rabbitmq: addresses: 127.0.0.1:5672 username: admin @@ -40,7 +40,7 @@ spring: # GrayEventInput: # consumer: # maxConcurrency: 1 #并发数 - # prefetch: 1 #从mq一次获取消息的数量 + # prefetch: 1 #从mq一次获取消息的数量 # requeueRejected: true #spring cloud stream 如果出现异常, 是否需要重新投递消息, false表示丢弃。 也有相应的Exception, true-MessageRejectedWhileStoppingException false-AmqpRejectAndDontRequeueException # auto-bind-dlq: true # acknowledgeMode: AUTO diff --git a/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/test/java/cn/springcloud/gray/service/test/GrayTrackServiceTest.java b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/test/java/cn/springcloud/gray/service/test/GrayTrackServiceTest.java new file mode 100644 index 00000000..094f40dd --- /dev/null +++ b/spring-cloud-gray-samples/spring-cloud-gray-server-sample/src/test/java/cn/springcloud/gray/service/test/GrayTrackServiceTest.java @@ -0,0 +1,53 @@ +package cn.springcloud.gray.service.test; + +import cn.springcloud.gray.server.app.GrayServerApplication; +import cn.springcloud.gray.server.module.domain.GrayTrack; +import cn.springcloud.gray.server.service.GrayTrackService; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@ActiveProfiles({"dev"}) +@RunWith(SpringRunner.class) +@SpringBootTest(classes = GrayServerApplication.class) +@Slf4j +public class GrayTrackServiceTest { + + @Autowired + private GrayTrackService grayTrackService; + + @Test + public void test1() { + GrayTrack grayTrack = GrayTrack.builder() + .id(1L) + .serviceId("a") + .instanceId("") + .name("test") + .infos("infos") + .build(); + + grayTrackService.saveModel(grayTrack); + + + grayTrackService.saveModel(GrayTrack.builder() + .serviceId("a") + .name("test2") + .infos("infos2") + .build()); + + grayTrackService.saveModel(GrayTrack.builder() + .serviceId("a") + .instanceId("a-1") + .name("test2") + .infos("infos2") + .build()); + + GrayTrack grayTrack1 = grayTrackService.findOneModel(1L); + log.info(grayTrack1.toString()); + + } +} diff --git a/spring-cloud-gray-samples/spring-cloud-gray-service-a-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-service-a-sample/pom.xml index f4bb4ae7..7d6a0317 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-service-a-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-service-a-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-service-a1-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-service-a1-sample/pom.xml index bc7ece69..5972f88a 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-service-a1-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-service-a1-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/pom.xml index d2c238a1..347c01f1 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/src/main/resources/config/application.yml b/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/src/main/resources/config/application.yml index 58cdcbc1..f2edcad7 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/src/main/resources/config/application.yml +++ b/spring-cloud-gray-samples/spring-cloud-gray-service-b-sample/src/main/resources/config/application.yml @@ -46,15 +46,18 @@ gray: request: track: web: - need: - uri: enable - ip: enable - method: enable - headers: test,test-mm - parameters: version,test + track-definitions: + - name: HttpIP + - name: HttpMethod + - name: HttpURI + - name: HttpReceive + - name: HttpHeader + value: test,test-mm + - name: HttpParameter + value: version,test path-patterns: /* load: - enabled: false + enabled: true gray-instances: - serviceId: service-a instance-id: service-a:20104 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-stream-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-stream-sample/pom.xml index 11963e01..cc96b623 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-stream-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-stream-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/pom.xml b/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/pom.xml index c6d36062..dbf75869 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/pom.xml +++ b/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray-samples cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/src/main/resources/config/application.yml b/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/src/main/resources/config/application.yml index bb4725bb..b159202d 100644 --- a/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/src/main/resources/config/application.yml +++ b/spring-cloud-gray-samples/spring-cloud-gray-zuul-sample/src/main/resources/config/application.yml @@ -50,12 +50,15 @@ gray: request: track: web: - need: - uri: enable - ip: enable - method: enable - headers: test,test-mm - parameters: version,test + track-definitions: + - name: HttpIP + - name: HttpMethod + - name: HttpURI + - name: HttpReceive + - name: HttpHeader + value: test,test-mm + - name: HttpParameter + value: version,test path-patterns: /* load: enabled: false diff --git a/spring-cloud-gray-server/pom.xml b/spring-cloud-gray-server/pom.xml index 392679b2..a1af1066 100644 --- a/spring-cloud-gray-server/pom.xml +++ b/spring-cloud-gray-server/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/DBStorageConfiguration.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/DBStorageConfiguration.java index 080d7159..df3c3cd7 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/DBStorageConfiguration.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/DBStorageConfiguration.java @@ -2,11 +2,10 @@ import cn.springcloud.gray.event.GrayEventPublisher; import cn.springcloud.gray.server.module.GrayServerModule; +import cn.springcloud.gray.server.module.GrayServerTrackModule; import cn.springcloud.gray.server.module.SimpleGrayServerModule; -import cn.springcloud.gray.server.service.GrayDecisionService; -import cn.springcloud.gray.server.service.GrayInstanceService; -import cn.springcloud.gray.server.service.GrayPolicyService; -import cn.springcloud.gray.server.service.GrayServiceService; +import cn.springcloud.gray.server.module.SimpleGrayServerTrackModule; +import cn.springcloud.gray.server.service.*; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; @@ -38,6 +37,13 @@ public GrayServerModule grayServerModule( GrayDecisionService grayDecisionService, GrayPolicyService grayPolicyService) { return new SimpleGrayServerModule(grayEventPublisher, grayServiceService, grayInstanceService, grayDecisionService, grayPolicyService); } + + + @Bean + public GrayServerTrackModule grayServerTrackModule(GrayEventPublisher grayEventPublisher, GrayTrackService grayTrackService) { + return new SimpleGrayServerTrackModule(grayEventPublisher, grayTrackService); + } + } @Bean diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/GrayServerAutoConfiguration.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/GrayServerAutoConfiguration.java index 84edfaeb..f3163d69 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/GrayServerAutoConfiguration.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/configuration/GrayServerAutoConfiguration.java @@ -1,15 +1,16 @@ package cn.springcloud.gray.server.configuration; import cn.springcloud.gray.event.GrayEventPublisher; -import cn.springcloud.gray.server.*; +import cn.springcloud.gray.server.GrayServerInitializingDestroyBean; import cn.springcloud.gray.server.configuration.properties.GrayServerProperties; import cn.springcloud.gray.server.event.DefaultGrayEventPublisher; import cn.springcloud.gray.server.evictor.GrayServerEvictor; import cn.springcloud.gray.server.evictor.NoActionGrayServerEvictor; import cn.springcloud.gray.server.manager.DefaultGrayServiceManager; import cn.springcloud.gray.server.manager.GrayServiceManager; -import cn.springcloud.gray.server.module.GrayModle; +import cn.springcloud.gray.server.module.GrayModule; import cn.springcloud.gray.server.module.GrayServerModule; +import cn.springcloud.gray.server.module.GrayServerTrackModule; import cn.springcloud.gray.server.module.SimpleGrayModule; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -57,11 +58,13 @@ public GrayServerEvictor grayServerEvictor() { @Bean @ConditionalOnMissingBean - public GrayModle grayModle(GrayServerModule grayServerModule, @Autowired(required = false) ObjectMapper objectMapper) { + public GrayModule grayModule( + GrayServerModule grayServerModule, GrayServerTrackModule grayServerTrackModule, + @Autowired(required = false) ObjectMapper objectMapper) { if (objectMapper == null) { objectMapper = new ObjectMapper(); } - return new SimpleGrayModule(grayServerModule, objectMapper); + return new SimpleGrayModule(grayServerModule, grayServerTrackModule, objectMapper); } @Bean diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/GrayTrackMapper.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/GrayTrackMapper.java new file mode 100644 index 00000000..711b27bf --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/GrayTrackMapper.java @@ -0,0 +1,14 @@ +package cn.springcloud.gray.server.dao.mapper; + +import cn.springcloud.gray.server.dao.model.GrayTrackDO; +import cn.springcloud.gray.server.module.domain.GrayTrack; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; + +@Mapper( + componentModel = "spring", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS +) +public interface GrayTrackMapper extends ModelMapper { + +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/ModelMapper.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/ModelMapper.java index 3a5a5104..dce2b235 100755 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/ModelMapper.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/mapper/ModelMapper.java @@ -1,5 +1,7 @@ package cn.springcloud.gray.server.dao.mapper; +import org.mapstruct.MappingTarget; + import java.util.List; /** @@ -13,5 +15,9 @@ public interface ModelMapper { MO do2model(DO d); - List dos2models(List d); + List dos2models(Iterable d); + + void do2model(DO d, @MappingTarget MO m); + + void model2do(MO m, @MappingTarget DO d); } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayDecisionDO.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayDecisionDO.java index e3bf6238..a2dcc110 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayDecisionDO.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayDecisionDO.java @@ -15,6 +15,7 @@ public class GrayDecisionDO { @Id @Column(length = 20) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(length = 20) private Long policyId; diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayInstanceDO.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayInstanceDO.java index ca6682d1..6e1c0bf3 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayInstanceDO.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayInstanceDO.java @@ -14,6 +14,7 @@ public class GrayInstanceDO { @Id @Column(length = 64) + @GeneratedValue(strategy = GenerationType.IDENTITY) private String instanceId; @Column(length = 32) private String serviceId; diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayPolicyDO.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayPolicyDO.java index 1eab9cf0..50570738 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayPolicyDO.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayPolicyDO.java @@ -15,6 +15,7 @@ public class GrayPolicyDO { @Id @Column(length = 20) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(length = 64) private String instanceId; diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayServiceDO.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayServiceDO.java index 9895cb13..12604d9e 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayServiceDO.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayServiceDO.java @@ -2,10 +2,7 @@ import lombok.*; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; @Setter @@ -19,6 +16,7 @@ public class GrayServiceDO { @Id @Column(length = 32) + @GeneratedValue(strategy = GenerationType.IDENTITY) private String serviceId; @Column(length = 64) private String serviceName; diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayTrackDO.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayTrackDO.java new file mode 100644 index 00000000..e9033de5 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/model/GrayTrackDO.java @@ -0,0 +1,28 @@ +package cn.springcloud.gray.server.dao.model; + +import lombok.*; + +import javax.persistence.*; + +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "gray_track", indexes = {@Index(columnList = "serviceId"), @Index(columnList = "instanceId")}) +public class GrayTrackDO { + + @Id +// @Column(length = 20) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Column(length = 32) + private String serviceId; + @Column(length = 64) + private String instanceId; + @Column(length = 64) + private String name; + @Column(length = 256) + private String infos; +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/repository/GrayTrackRepository.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/repository/GrayTrackRepository.java new file mode 100644 index 00000000..988553f1 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/dao/repository/GrayTrackRepository.java @@ -0,0 +1,26 @@ +package cn.springcloud.gray.server.dao.repository; + +import cn.springcloud.gray.server.dao.model.GrayTrackDO; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface GrayTrackRepository extends JpaRepository { + + + Page findAllByInstanceId(String instanceId, Pageable pageable); + + List findAllByInstanceId(String instanceId); + + @Query(value = "SELECT do FROM GrayTrackDO do WHERE serviceId = ?1 AND (instanceId = null or instanceId='') ") + List findAllByServiceIdAndInstanceIdIsEmpty(String serviceId); + + + @Query(value = "SELECT do FROM GrayTrackDO do WHERE serviceId = ?1 AND (instanceId = null or instanceId='') ") + Page findAllByServiceIdAndInstanceIdIsEmpty(String instanceId, Pageable pageable); +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/event/stream/StreamGrayEventPublisher.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/event/stream/StreamGrayEventPublisher.java index 9282fc90..d8b97753 100755 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/event/stream/StreamGrayEventPublisher.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/event/stream/StreamGrayEventPublisher.java @@ -6,9 +6,15 @@ import cn.springcloud.gray.exceptions.EventException; import org.springframework.messaging.support.MessageBuilder; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + public class StreamGrayEventPublisher implements GrayEventPublisher { + private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1); + private StreamOutput sender; public StreamGrayEventPublisher(StreamOutput sender) { @@ -21,6 +27,6 @@ public boolean send(Object obj) { @Override public void publishEvent(GrayEventMsg msg) throws EventException { - send(msg); + executorService.schedule(() -> send(msg), 100, TimeUnit.MILLISECONDS); } } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModle.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModule.java similarity index 61% rename from spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModle.java rename to spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModule.java index 8b2e36b2..f1038676 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModle.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayModule.java @@ -1,14 +1,18 @@ package cn.springcloud.gray.server.module; import cn.springcloud.gray.model.GrayInstance; +import cn.springcloud.gray.model.GrayTrackDefinition; import java.util.List; -public interface GrayModle { +public interface GrayModule { GrayServerModule getGrayServerModule(); List allOpenInstances(); GrayInstance getGrayInstance(String serviceId, String instanceId); + + + List getTrackDefinitions(String serviceId, String instanceId); } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayServerTrackModule.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayServerTrackModule.java new file mode 100644 index 00000000..39504bd3 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/GrayServerTrackModule.java @@ -0,0 +1,23 @@ +package cn.springcloud.gray.server.module; + +import cn.springcloud.gray.server.module.domain.GrayTrack; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface GrayServerTrackModule { + + + List listGrayTracksEmptyInstanceByServiceId(String serviceId); + + List listGrayTracksByInstanceId(String instanceId); + + Page listGrayTracksEmptyInstanceByServiceId(String serviceId, Pageable pageable); + + Page listGrayTracksByInstanceId(String instanceId, Pageable pageable); + + void deleteGrayTrack(Long id); + + void saveGrayTrack(GrayTrack track); +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayModule.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayModule.java index 825e2cf6..89faa743 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayModule.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayModule.java @@ -1,11 +1,9 @@ package cn.springcloud.gray.server.module; -import cn.springcloud.gray.model.DecisionDefinition; -import cn.springcloud.gray.model.GrayInstance; -import cn.springcloud.gray.model.GrayStatus; -import cn.springcloud.gray.model.PolicyDefinition; +import cn.springcloud.gray.model.*; import cn.springcloud.gray.server.module.domain.GrayDecision; import cn.springcloud.gray.server.module.domain.GrayPolicy; +import cn.springcloud.gray.server.module.domain.GrayTrack; import cn.springcloud.gray.server.module.domain.InstanceStatus; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -18,13 +16,18 @@ import java.util.Map; @Slf4j -public class SimpleGrayModule implements GrayModle { +public class SimpleGrayModule implements GrayModule { private GrayServerModule grayServerModule; + private GrayServerTrackModule grayServerTrackModule; private ObjectMapper objectMapper; - public SimpleGrayModule(GrayServerModule grayServerModule, ObjectMapper objectMapper) { + public SimpleGrayModule( + GrayServerModule grayServerModule, + GrayServerTrackModule grayServerTrackModule, + ObjectMapper objectMapper) { this.grayServerModule = grayServerModule; + this.grayServerTrackModule = grayServerTrackModule; this.objectMapper = objectMapper; } @@ -42,6 +45,29 @@ public GrayInstance getGrayInstance(String serviceId, String instanceId) { return ofGrayInstanceInfo(grayInstance); } + @Override + public List getTrackDefinitions(String serviceId, String instanceId) { + List grayTracks = grayServerTrackModule.listGrayTracksEmptyInstanceByServiceId(serviceId); + List trackDefinitions = new ArrayList<>(grayTracks.size()); + addGrayTrackDefinitions(trackDefinitions, grayTracks); + addGrayTrackDefinitions(trackDefinitions, grayServerTrackModule.listGrayTracksByInstanceId(instanceId)); + return trackDefinitions; + } + + private void addGrayTrackDefinitions(List trackDefinitions, List grayTracks) { + grayTracks.forEach(track -> { + trackDefinitions.add(ofGrayTrack(track)); + }); + } + + + private GrayTrackDefinition ofGrayTrack(GrayTrack grayTrack) { + GrayTrackDefinition definition = new GrayTrackDefinition(); + definition.setName(grayTrack.getName()); + definition.setValue(grayTrack.getInfos()); + return definition; + } + @Override public List allOpenInstances() { diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerModule.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerModule.java index a16aaba4..5efc37b9 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerModule.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerModule.java @@ -3,6 +3,7 @@ import cn.springcloud.gray.event.EventType; import cn.springcloud.gray.event.GrayEventMsg; import cn.springcloud.gray.event.GrayEventPublisher; +import cn.springcloud.gray.event.SourceType; import cn.springcloud.gray.model.GrayStatus; import cn.springcloud.gray.server.module.domain.*; import cn.springcloud.gray.server.service.GrayDecisionService; @@ -225,6 +226,7 @@ private void publishGrayEvent(String serviceId, String instanceId, EventType eve eventMsg.setInstanceId(instanceId); eventMsg.setServiceId(serviceId); eventMsg.setEventType(eventType); + eventMsg.setSourceType(SourceType.GRAY_INSTANCE); publishGrayEvent(eventMsg); } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerTrackModule.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerTrackModule.java new file mode 100644 index 00000000..4e827c73 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/SimpleGrayServerTrackModule.java @@ -0,0 +1,85 @@ +package cn.springcloud.gray.server.module; + +import cn.springcloud.gray.event.EventType; +import cn.springcloud.gray.event.GrayEventMsg; +import cn.springcloud.gray.event.GrayEventPublisher; +import cn.springcloud.gray.event.SourceType; +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.server.module.domain.GrayTrack; +import cn.springcloud.gray.server.service.GrayTrackService; +import org.apache.commons.lang.StringUtils; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public class SimpleGrayServerTrackModule implements GrayServerTrackModule { + + private GrayEventPublisher grayEventPublisher; + private GrayTrackService grayTrackService; + + public SimpleGrayServerTrackModule(GrayEventPublisher grayEventPublisher, GrayTrackService grayTrackService) { + this.grayEventPublisher = grayEventPublisher; + this.grayTrackService = grayTrackService; + } + + @Override + public List listGrayTracksEmptyInstanceByServiceId(String serviceId) { + return grayTrackService.listGrayTracksEmptyInstanceByServiceId(serviceId); + } + + @Override + public List listGrayTracksByInstanceId(String instanceId) { + return grayTrackService.listGrayTracksByInstanceId(instanceId); + } + + @Override + public Page listGrayTracksEmptyInstanceByServiceId(String serviceId, Pageable pageable) { + return grayTrackService.listGrayTracksEmptyInstanceByServiceId(serviceId, pageable); + } + + @Override + public Page listGrayTracksByInstanceId(String instanceId, Pageable pageable) { + return grayTrackService.listGrayTracksByInstanceId(instanceId, pageable); + } + + @Override + public void deleteGrayTrack(Long id) { + GrayTrack grayTrack = grayTrackService.findOneModel(id); + grayTrackService.delete(id); + publishGrayTrackEvent(EventType.DOWN, grayTrack); + } + + @Override + public void saveGrayTrack(GrayTrack track) { + GrayTrack pre = null; + if (track.getId() != null) { + pre = grayTrackService.findOneModel(track.getId()); + } + grayTrackService.saveModel(track); + if (pre != null) { + if (!StringUtils.equals(pre.getServiceId(), track.getServiceId()) || + !StringUtils.equals(pre.getInstanceId(), track.getInstanceId())) { + publishGrayTrackEvent(EventType.DOWN, pre); + } + } + publishGrayTrackEvent(EventType.UPDATE, track); + } + + protected void publishGrayTrackEvent(EventType eventType, GrayTrack grayTrack) { + GrayEventMsg eventMsg = new GrayEventMsg(); + eventMsg.setInstanceId(grayTrack.getInstanceId()); + eventMsg.setServiceId(grayTrack.getServiceId()); + eventMsg.setEventType(eventType); + eventMsg.setSourceType(SourceType.GRAY_TRACK); + GrayTrackDefinition definition = new GrayTrackDefinition(); + definition.setName(grayTrack.getName()); + definition.setValue(grayTrack.getInfos()); + eventMsg.setExtra(definition); + publishGrayEvent(eventMsg); + } + + protected void publishGrayEvent(GrayEventMsg eventMsg) { + grayEventPublisher.publishEvent(eventMsg); + } +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/domain/GrayTrack.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/domain/GrayTrack.java new file mode 100644 index 00000000..1c2af430 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/module/domain/GrayTrack.java @@ -0,0 +1,16 @@ +package cn.springcloud.gray.server.module.domain; + +import lombok.*; + +@Setter +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GrayTrack { + private Long id; + private String serviceId; + private String instanceId; + private String name; + private String infos; +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayResource.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayResource.java index 7665ed2e..7b45e47a 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayResource.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayResource.java @@ -1,9 +1,8 @@ package cn.springcloud.gray.server.resources.rest; import cn.springcloud.gray.model.GrayInstance; -import cn.springcloud.gray.server.discovery.ServiceDiscover; -import cn.springcloud.gray.server.module.GrayModle; -import cn.springcloud.gray.server.module.GrayServerModule; +import cn.springcloud.gray.model.GrayTrackDefinition; +import cn.springcloud.gray.server.module.GrayModule; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -21,20 +20,26 @@ public class GrayResource { @Autowired - private GrayModle grayModle; + private GrayModule grayModule; @ApiOperation("返回所有已经打开灰度状态的实例信息(包含决策信息)") @RequestMapping(value = "/instances/enable", method = RequestMethod.GET) public List allOpens() { - return grayModle.allOpenInstances(); + return grayModule.allOpenInstances(); } @ApiOperation("返回指定实例的信息(包含决策信息)") @RequestMapping(value = "/instance", method = RequestMethod.GET) public GrayInstance instance(@RequestParam("serviceId") String serviceId, @RequestParam("instanceId") String instanceId) { - return grayModle.getGrayInstance(serviceId, instanceId); + return grayModule.getGrayInstance(serviceId, instanceId); + } + + @ApiOperation("返回指定实例的灰度追踪信息(包含决策信息)") + @RequestMapping(value = "/trackDefinitions", method = RequestMethod.GET) + public List trackDefinitions(@RequestParam("serviceId") String serviceId, @RequestParam("instanceId") String instanceId) { + return grayModule.getTrackDefinitions(serviceId, instanceId); } } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayTrackResource.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayTrackResource.java new file mode 100644 index 00000000..0ca8441e --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/resources/rest/GrayTrackResource.java @@ -0,0 +1,71 @@ +package cn.springcloud.gray.server.resources.rest; + +import cn.springcloud.gray.server.module.GrayServerTrackModule; +import cn.springcloud.gray.server.module.domain.GrayTrack; +import cn.springcloud.gray.server.utils.PaginationUtils; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/gray/track") +public class GrayTrackResource { + + @Autowired + private GrayServerTrackModule grayServerTrackModule; + + @RequestMapping(value = "listByInstance", method = RequestMethod.GET, params = "instanceId") + public List listByInstance(@RequestParam("instanceId") String instanceId) { + return grayServerTrackModule.listGrayTracksByInstanceId(instanceId); + } + + + @GetMapping(value = "/pageByInstance") + public ResponseEntity> pageByInstance( + @RequestParam("instanceId") String instanceId, + @ApiParam @PageableDefault(direction = Sort.Direction.DESC) Pageable pageable) { + Page page = grayServerTrackModule.listGrayTracksByInstanceId(instanceId, pageable); + HttpHeaders headers = PaginationUtils.generatePaginationHttpHeaders(page); + return new ResponseEntity>( + page.getContent(), + headers, + HttpStatus.OK); + } + + @RequestMapping(value = "listByService", method = RequestMethod.GET, params = "serviceId") + public List listByService(@RequestParam("serviceId") String serviceId) { + return grayServerTrackModule.listGrayTracksEmptyInstanceByServiceId(serviceId); + } + + + @GetMapping(value = "/pageByService") + public ResponseEntity> pageByService( + @RequestParam("serviceId") String serviceId, + @ApiParam @PageableDefault(direction = Sort.Direction.DESC) Pageable pageable) { + Page page = grayServerTrackModule.listGrayTracksEmptyInstanceByServiceId(serviceId, pageable); + HttpHeaders headers = PaginationUtils.generatePaginationHttpHeaders(page); + return new ResponseEntity>( + page.getContent(), + headers, + HttpStatus.OK); + } + + @RequestMapping(value = "{id}", method = RequestMethod.DELETE) + public void delete(@PathVariable("id") Long id) { + grayServerTrackModule.deleteGrayTrack(id); + } + + @RequestMapping(value = "/", method = RequestMethod.POST) + public void save(@RequestBody GrayTrack track) { + grayServerTrackModule.saveGrayTrack(track); + } +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/AbstraceCRUDService.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/AbstraceCRUDService.java index 956b7f2f..73bef1ea 100644 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/AbstraceCRUDService.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/AbstraceCRUDService.java @@ -3,6 +3,7 @@ import cn.springcloud.gray.server.dao.mapper.ModelMapper; import org.springframework.data.jpa.repository.JpaRepository; +import javax.transaction.Transactional; import java.io.Serializable; import java.util.List; @@ -17,16 +18,19 @@ protected void save(T entity) { getRepository().save(entity); } + @Transactional public void saveModel(MODEL entity) { - save(getModelMapper().model2do(entity)); + T t = model2do(entity); + save(t); + } - protected List save(Iterable entities) { + protected Iterable save(Iterable entities) { return getRepository().save(entities); } public List saveModels(Iterable entities) { - return getModelMapper().dos2models(save(getModelMapper().models2dos(entities))); + return dos2models(save(models2dos(entities))); } protected T findOne(ID id) { @@ -34,7 +38,7 @@ protected T findOne(ID id) { } public MODEL findOneModel(ID id) { - return getModelMapper().do2model(findOne(id)); + return do2model(findOne(id)); } @@ -42,20 +46,20 @@ public boolean exists(ID id) { return getRepository().exists(id); } - protected List findAll() { + protected Iterable findAll() { return getRepository().findAll(); } - protected List findAll(Iterable ids) { + protected Iterable findAll(Iterable ids) { return getRepository().findAll(ids); } public List findAllModel() { - return getModelMapper().dos2models(findAll()); + return dos2models(findAll()); } public List findAllModel(Iterable ids) { - return getModelMapper().dos2models(findAll(ids)); + return dos2models(findAll(ids)); } @@ -73,7 +77,7 @@ protected void delete(Iterable entities) { } public void deleteModel(Iterable models) { - delete(getModelMapper().models2dos(models)); + delete(models2dos(models)); } public void deleteAll() { @@ -81,4 +85,30 @@ public void deleteAll() { } + protected List dos2models(Iterable dos) { + return getModelMapper().dos2models(dos); + } + + protected List models2dos(Iterable models) { + return getModelMapper().models2dos(models); + } + + + protected MODEL do2model(T t) { + return getModelMapper().do2model(t); + } + + + protected T model2do(MODEL model) { + return getModelMapper().model2do(model); + } + + protected void do2model(T t, MODEL model) { + getModelMapper().do2model(t, model); + } + + protected void model2do(MODEL model, T t) { + getModelMapper().model2do(model, t); + } + } diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/GrayTrackService.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/GrayTrackService.java new file mode 100644 index 00000000..8fa27468 --- /dev/null +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/service/GrayTrackService.java @@ -0,0 +1,51 @@ +package cn.springcloud.gray.server.service; + +import cn.springcloud.gray.server.dao.mapper.GrayTrackMapper; +import cn.springcloud.gray.server.dao.model.GrayTrackDO; +import cn.springcloud.gray.server.dao.repository.GrayTrackRepository; +import cn.springcloud.gray.server.module.domain.GrayTrack; +import cn.springcloud.gray.server.utils.PaginationUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class GrayTrackService extends AbstraceCRUDService { + + @Autowired + private GrayTrackRepository repository; + @Autowired + private GrayTrackMapper grayTrackMapper; + + @Override + protected GrayTrackRepository getRepository() { + return repository; + } + + @Override + protected GrayTrackMapper getModelMapper() { + return grayTrackMapper; + } + + public List listGrayTracksEmptyInstanceByServiceId(String serviceId) { + return dos2models(repository.findAllByServiceIdAndInstanceIdIsEmpty(serviceId)); + } + + public List listGrayTracksByInstanceId(String instanceId) { + return dos2models(repository.findAllByInstanceId(instanceId)); + } + + public Page listGrayTracksEmptyInstanceByServiceId(String serviceId, Pageable pageable) { + Page page = repository.findAllByServiceIdAndInstanceIdIsEmpty(serviceId, pageable); + return PaginationUtils.convert(pageable, page, getModelMapper()); + } + + public Page listGrayTracksByInstanceId(String instanceId, Pageable pageable) { + Page page = repository.findAllByInstanceId(instanceId, pageable); + return PaginationUtils.convert(pageable, page, getModelMapper()); + + } +} diff --git a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/utils/PaginationUtils.java b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/utils/PaginationUtils.java index 1d611905..497e5336 100755 --- a/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/utils/PaginationUtils.java +++ b/spring-cloud-gray-server/src/main/java/cn/springcloud/gray/server/utils/PaginationUtils.java @@ -27,6 +27,10 @@ public static Page convert(Pageable pageable, Page p, Model return new PageImpl(list, pageable, p.getTotalElements()); } + public static Page convert(Pageable pageable, Page p, List models) { + return new PageImpl(models, pageable, p.getTotalElements()); + } + public static HttpHeaders generatePaginationHttpHeaders(Page page) { return generatePaginationHttpHeaders(page, null); diff --git a/spring-cloud-gray-starter-dependencies/pom.xml b/spring-cloud-gray-starter-dependencies/pom.xml index 0387814e..c686c071 100644 --- a/spring-cloud-gray-starter-dependencies/pom.xml +++ b/spring-cloud-gray-starter-dependencies/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-utils/pom.xml b/spring-cloud-gray-utils/pom.xml index 09fe2e4b..c57924e2 100644 --- a/spring-cloud-gray-utils/pom.xml +++ b/spring-cloud-gray-utils/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-gray-webui/pom.xml b/spring-cloud-gray-webui/pom.xml index 93cea733..a16291d1 100644 --- a/spring-cloud-gray-webui/pom.xml +++ b/spring-cloud-gray-webui/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-starter-gray-client/pom.xml b/spring-cloud-starter-gray-client/pom.xml index 1c71865c..823d6925 100644 --- a/spring-cloud-starter-gray-client/pom.xml +++ b/spring-cloud-starter-gray-client/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0 diff --git a/spring-cloud-starter-gray-client/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-gray-client/src/main/resources/META-INF/spring.factories index a0c8923c..7d3c2169 100644 --- a/spring-cloud-starter-gray-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-starter-gray-client/src/main/resources/META-INF/spring.factories @@ -1,10 +1,11 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cn.springcloud.gray.client.config.GrayClientAutoConfiguration,\ - cn.springcloud.gray.client.config.GrayLoadAutoConfigration,\ +cn.springcloud.gray.client.config.GrayClientAutoConfiguration,\ + cn.springcloud.gray.client.config.GrayLoadAutoConfigration,\ cn.springcloud.gray.client.netflix.configuration.NetflixGrayAutoConfiguration,\ cn.springcloud.gray.client.netflix.configuration.GrayClientEurekaAutoConfiguration,\ cn.springcloud.gray.client.netflix.feign.configuration.GrayFeignAutoConfiguration,\ cn.springcloud.gray.client.netflix.zuul.configuration.GrayZuulAutoConfiguration,\ cn.springcloud.gray.client.netflix.resttemplate.configuration.GrayRestTemplateAutoConfiguration,\ - cn.springcloud.gray.client.config.GrayEventAutoConfiguration \ No newline at end of file + cn.springcloud.gray.client.config.GrayEventAutoConfiguration,\ +cn.springcloud.gray.client.config.GrayClientBeanPostProcessorConfiguration \ No newline at end of file diff --git a/spring-cloud-starter-gray-server/pom.xml b/spring-cloud-starter-gray-server/pom.xml index f8ec415b..95b5f717 100644 --- a/spring-cloud-starter-gray-server/pom.xml +++ b/spring-cloud-starter-gray-server/pom.xml @@ -5,7 +5,7 @@ spring-cloud-gray cn.springcloud.gray - 2.0.0 + 2.1.0 4.0.0