From 6d240ef2433f384afedb6e804d73f7d570571d4b Mon Sep 17 00:00:00 2001 From: tanghc Date: Wed, 21 Aug 2019 17:58:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81easyopen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/ServiceRoutesLoader.java | 20 ++-- .../gatewaycommon/validate/ApiValidator.java | 4 +- .../zuul/param/ZuulParamBuilder.java | 4 + .../EasyopenServiceConfiguration.java | 92 ------------------- .../easyopen/EasyopenApiMetaBuilder.java | 91 ++++++++++++++++++ .../EasyopenServiceConfiguration.java | 24 +++++ .../EasyopenServiceRouteController.java | 24 +++++ .../manager/ServiceRouteController.java | 6 +- .../manager/ServiceRouteInfoBuilder.java | 4 + 9 files changed, 166 insertions(+), 103 deletions(-) delete mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenApiMetaBuilder.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceConfiguration.java create mode 100644 sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceRouteController.java diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java index ad28c439..88dc0e96 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/ServiceRoutesLoader.java @@ -20,7 +20,9 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.DigestUtils; import org.springframework.web.client.RestTemplate; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -46,15 +48,9 @@ public class ServiceRoutesLoader { private RestTemplate restTemplate = new RestTemplate(); - private volatile long lastUpdateTime; + private Map updateTimeMap = new HashMap<>(16); public synchronized void load(ApplicationEvent event) { - long now = System.currentTimeMillis(); - // 5秒内只能执行一次,解决重启应用连续加载4次问题 - if (now - lastUpdateTime < FIVE_SECONDS) { - return; - } - lastUpdateTime = now; NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); List subscribes = null; try { @@ -74,6 +70,14 @@ public class ServiceRoutesLoader { if (Objects.equals(thisServiceId, serviceName)) { continue; } + // nacos会不停的触发事件,这里做了一层拦截 + // 同一个serviceId5秒内允许访问一次 + Long lastUpdateTime = updateTimeMap.getOrDefault(serviceName, 0L); + long now = System.currentTimeMillis(); + if (now - lastUpdateTime < FIVE_SECONDS) { + continue; + } + updateTimeMap.put(serviceName, now); try { String dataId = NacosConfigs.getRouteDataId(serviceName); String groupId = NacosConfigs.GROUP_ROUTE; @@ -85,7 +89,7 @@ public class ServiceRoutesLoader { configService.removeConfig(dataId, groupId); } else { for (Instance instance : allInstances) { - log.info("加载服务路由,instance:{}", instance); + log.info("加载服务路由,serviceId:{}, instance:{}",serviceName, instance); String url = getRouteRequestUrl(instance); ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); if (responseEntity.getStatusCode() == HttpStatus.OK) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java index a8ed1357..75ee6e42 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java @@ -48,7 +48,7 @@ public class ApiValidator implements Validator { private IsvManager isvManager; @Autowired - private IsvRoutePermissionManager isvRoutePermissionManager; + private IsvRoutePermissionManager isvRoutePermissionManager; @Autowired private IPBlacklistManager ipBlacklistManager; @@ -59,7 +59,6 @@ public class ApiValidator implements Validator { @Override public void validate(ApiParam param) { checkIP(param); - checkEnable(param); ApiConfig apiConfig = ApiContext.getApiConfig(); if (apiConfig.isIgnoreValidate() || param.fetchIgnoreValidate()) { @@ -68,6 +67,7 @@ public class ApiValidator implements Validator { } return; } + checkEnable(param); // 需要验证签名,先校验appKey,后校验签名,顺序不能变 checkAppKey(param); checkSign(param); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java index 032de9d8..d99cb846 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java @@ -5,6 +5,7 @@ import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.BaseParamBuilder; import com.gitee.sop.gatewaycommon.util.RequestUtil; import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.http.HttpServletRequestWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.lang3.StringUtils; @@ -26,6 +27,9 @@ public class ZuulParamBuilder extends BaseParamBuilder { @Override public Map buildRequestParams(RequestContext ctx) { HttpServletRequest request = ctx.getRequest(); + if (request instanceof HttpServletRequestWrapper) { + request = ((HttpServletRequestWrapper) request).getRequest(); + } Map params; if (GET.equalsIgnoreCase(request.getMethod())) { params = RequestUtil.convertRequestParamsToMap(request); diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java deleted file mode 100644 index 075db50f..00000000 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.gitee.sop.servercommon.configuration; - -import com.gitee.easyopen.ApiContext; -import com.gitee.easyopen.annotation.Api; -import com.gitee.easyopen.util.ReflectionUtil; -import com.gitee.sop.servercommon.bean.ServiceApiInfo; -import com.gitee.sop.servercommon.manager.ApiMetaManager; -import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -/** - * 提供给easyopen项目使用 - * - * @author tanghc - */ -public class EasyopenServiceConfiguration extends BaseServiceConfiguration { - - static { - ApiContext.getApiConfig().setIgnoreValidate(true); - } - - class EasyopenRequestMappingEvent extends DefaultRequestMappingEvent { - String prefixPath; - - public EasyopenRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) { - super(apiMetaManager, environment); - - String path = getEnvironment().getProperty("easyopen.prefix-path"); - if (path == null) { - throw new IllegalArgumentException("请在application.propertis中设置easyopen.prefix-path属性,填IndexController上面的@RequestMapping()中的值"); - } - this.prefixPath = path; - } - - @Override - protected List buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) { - ApplicationContext ctx = getApplicationContext(); - String[] apiServiceNames = ReflectionUtil.findApiServiceNames(ctx); - List apiMetaList = new ArrayList<>(); - for (String apiServiceName : apiServiceNames) { - Object bean = ctx.getBean(apiServiceName); - doWithMethods(bean.getClass(), method -> { - Api api = AnnotationUtils.findAnnotation(method, Api.class); - ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(); - apiMeta.setName(api.name()); - apiMeta.setVersion(api.version()); - apiMeta.setIgnoreValidate(BooleanUtils.toInteger(api.ignoreValidate())); - // 对结果不合并 - apiMeta.setMergeResult(BooleanUtils.toInteger(false)); - // /api/goods.get/ - String servletPath = this.buildPath(api); - apiMeta.setPath(servletPath); - apiMetaList.add(apiMeta); - }); - } - return apiMetaList; - } - - protected void doWithMethods(Class clazz, Consumer consumer) { - // Keep backing up the inheritance hierarchy. - Method[] methods = clazz.getDeclaredMethods(); - for (Method method : methods) { - boolean match = !method.isSynthetic() && AnnotationUtils.findAnnotation(method, Api.class) != null; - if (match) { - consumer.accept(method); - } - } - } - - protected String buildPath(Api api) { - // /api/goods.get/ - String servletPath = prefixPath + "/" + api.name() + "/"; - String version = api.version(); - if (StringUtils.hasLength(version)) { - // /api/goods.get/1.0/ - servletPath = servletPath + version + "/"; - } - return servletPath; - } - } - -} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenApiMetaBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenApiMetaBuilder.java new file mode 100644 index 00000000..adcd450f --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenApiMetaBuilder.java @@ -0,0 +1,91 @@ +package com.gitee.sop.servercommon.easyopen; + +import com.gitee.easyopen.annotation.Api; +import com.gitee.easyopen.util.ReflectionUtil; +import com.gitee.sop.servercommon.bean.ServiceApiInfo; +import com.gitee.sop.servercommon.manager.ApiMetaBuilder; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * @author tanghc + */ +public class EasyopenApiMetaBuilder extends ApiMetaBuilder { + + /** IndexController上面的@RequestMapping()中的值,如:/api */ + private final String prefixPath; + + private final String contextPath; + + private ApplicationContext applicationContext; + + private Environment environment; + + public EasyopenApiMetaBuilder(ApplicationContext applicationContext, Environment environment) { + this.applicationContext = applicationContext; + this.environment = environment; + String path = environment.getProperty("easyopen.prefix-path"); + if (path == null) { + throw new IllegalArgumentException("请在application.propertis中设置easyopen.prefix-path属性,填IndexController上面的@RequestMapping()中的值"); + } + if (!path.startsWith("/")) { + path = "/" + path; + } + this.prefixPath = path; + this.contextPath = environment.getProperty("server.servlet.context-path", "/"); + } + + @Override + protected List buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) { + String[] apiServiceNames = ReflectionUtil.findApiServiceNames(applicationContext); + List apiMetaList = new ArrayList<>(); + for (String apiServiceName : apiServiceNames) { + Object bean = applicationContext.getBean(apiServiceName); + doWithMethods(bean.getClass(), method -> { + Api api = AnnotationUtils.findAnnotation(method, Api.class); + ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(); + apiMeta.setName(api.name()); + apiMeta.setVersion(api.version()); + apiMeta.setIgnoreValidate(BooleanUtils.toInteger(api.ignoreValidate())); + // 对结果不合并 + apiMeta.setMergeResult(BooleanUtils.toInteger(false)); + // /api/goods.get/ + String servletPath = this.buildPath(api); + apiMeta.setPath(servletPath); + apiMetaList.add(apiMeta); + }); + } + return apiMetaList; + } + + protected void doWithMethods(Class clazz, Consumer consumer) { + // Keep backing up the inheritance hierarchy. + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + boolean match = !method.isSynthetic() && AnnotationUtils.findAnnotation(method, Api.class) != null; + if (match) { + consumer.accept(method); + } + } + } + + protected String buildPath(Api api) { + // /api/goods.get/ + String servletPath = prefixPath + "/" + api.name() + "/"; + String version = api.version(); + if (StringUtils.hasLength(version)) { + // /api/goods.get/1.0/ + servletPath = servletPath + version + "/"; + } + return contextPath + prefixPath + servletPath; + } +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceConfiguration.java new file mode 100644 index 00000000..a84bf30f --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceConfiguration.java @@ -0,0 +1,24 @@ +package com.gitee.sop.servercommon.easyopen; + +import com.gitee.easyopen.ApiContext; +import com.gitee.sop.servercommon.configuration.BaseServiceConfiguration; +import com.gitee.sop.servercommon.manager.ServiceRouteController; +import org.springframework.context.annotation.Bean; + +/** + * 提供给easyopen项目使用 + * + * @author tanghc + */ +public class EasyopenServiceConfiguration extends BaseServiceConfiguration { + + static { + ApiContext.getApiConfig().setIgnoreValidate(true); + } + + @Bean + ServiceRouteController serviceRouteController() { + return new EasyopenServiceRouteController(); + } + +} diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceRouteController.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceRouteController.java new file mode 100644 index 00000000..c07623a2 --- /dev/null +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/easyopen/EasyopenServiceRouteController.java @@ -0,0 +1,24 @@ +package com.gitee.sop.servercommon.easyopen; + +import com.gitee.sop.servercommon.manager.ApiMetaBuilder; +import com.gitee.sop.servercommon.manager.ServiceRouteController; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class EasyopenServiceRouteController extends ServiceRouteController implements ApplicationContextAware { + + private ApplicationContext applicationContext; + + @Override + protected ApiMetaBuilder getApiMetaBuilder() { + return new EasyopenApiMetaBuilder(applicationContext, getEnvironment()); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} \ No newline at end of file diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java index c7d541f8..50ddca39 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteController.java @@ -40,9 +40,13 @@ public class ServiceRouteController { return getServiceRouteInfo(request, response); } + protected ApiMetaBuilder getApiMetaBuilder() { + return new ApiMetaBuilder(); + } + protected ServiceRouteInfo getServiceRouteInfo(HttpServletRequest request, HttpServletResponse response) { String serviceId = environment.getProperty("spring.application.name"); - ApiMetaBuilder apiMetaBuilder = new ApiMetaBuilder(); + ApiMetaBuilder apiMetaBuilder = getApiMetaBuilder(); ServiceApiInfo serviceApiInfo = apiMetaBuilder.getServiceApiInfo(serviceId, requestMappingHandlerMapping); ServiceRouteInfoBuilder serviceRouteInfoBuilder = new ServiceRouteInfoBuilder(environment); return serviceRouteInfoBuilder.build(serviceApiInfo); diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java index 868a8756..c61bd107 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceRouteInfoBuilder.java @@ -147,4 +147,8 @@ public class ServiceRouteInfoBuilder { throw new IllegalArgumentException(errorMsg); } } + + public Environment getEnvironment() { + return environment; + } }