diff --git a/README.md b/README.md
index bdf76e95..8512f4f7 100644
--- a/README.md
+++ b/README.md
@@ -35,11 +35,11 @@ SOP封装了开放平台大部分功能包括:签名验证、统一异常处
- 秘钥管理
- 微服务端自动验证(JSR-303)
- 支持Spring Cloud Gateway
+- 关闭签名校验功能
+- 整合[easyopen](https://gitee.com/durcframework/easyopen)
## 后期规划
-- 关闭签名校验功能
-- 整合[easyopen](https://gitee.com/durcframework/easyopen)
- 配置中心,Spring Cloud Config(Zookeeper)
- Admin管理平台,统一管理微服务配置,管理路由信息,微服务上下线,API文档管理等功能
diff --git a/sop-gateway-common/pom.xml b/sop-gateway-common/pom.xml
index 02114892..6a4d2c6f 100644
--- a/sop-gateway-common/pom.xml
+++ b/sop-gateway-common/pom.xml
@@ -2,21 +2,19 @@
4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 2.1.2.RELEASE
-
-
com.gitee.sop
sop-gateway-common
1.0.0-SNAPSHOT
+ jar
sop-gateway-common
sop-gateway-common
1.8
Greenwich.RELEASE
+ 2.1.2.RELEASE
+ 1.8
+ 1.8
1.0.13
1.7.5
@@ -28,28 +26,44 @@
2.5
1.3.3
3.2.2
- 1.4.7
- 1.7
- 6.0.10.Final
- 0.31
- 3.2.0
- 18.0
- 1.8.8.RELEASE
- 4.1.25.Final
- 2.0.5.Final
- 5.5.12
- 5.5.8
- 5.2.0
- 6.2
+ 3.8.1
1.11
+ 1.4.7
+ 3.4.12
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
org.springframework.cloud
spring-cloud-starter-netflix-zuul
true
+
+ org.springframework.cloud
+ spring-cloud-netflix-ribbon
+ compile
+
+
org.springframework.cloud
spring-cloud-starter-gateway
@@ -60,10 +74,6 @@
spring-boot-starter-webflux
true
-
- org.springframework.boot
- spring-boot-starter-actuator
-
@@ -84,7 +94,7 @@
org.apache.zookeeper
zookeeper
- 3.4.12
+ ${zookeeper.version}
org.slf4j
@@ -93,11 +103,17 @@
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
org.springframework.boot
spring-boot-starter-test
test
+
com.thoughtworks.xstream
xstream
@@ -109,15 +125,11 @@
fastjson
${fastjson.version}
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
org.apache.commons
commons-lang3
- 3.8.1
+ ${commons-lang3.version}
commons-collections
@@ -151,42 +163,60 @@
3.1.0
provided
-
- org.springframework.cloud
- spring-cloud-netflix-ribbon
- 2.1.0.RELEASE
- compile
-
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
-
+
- org.springframework.boot
- spring-boot-maven-plugin
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9
+
+
+ attach-javadocs
+
+ jar
+
+
+
+ -Xdoclint:none
+
+
+
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/milestone
-
-
-
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java
index ad230a20..13c7b25e 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java
@@ -95,6 +95,11 @@ public class ApiConfig {
*/
private boolean ignoreValidate;
+ /**
+ * 是否对结果进行合并
+ */
+ private boolean mergeResult = true;
+
/**
* 超时时间
*/
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java
index 2b51ef4f..e95605ca 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/BaseRouteDefinition.java
@@ -21,4 +21,9 @@ public class BaseRouteDefinition {
* 路由执行的顺序
*/
private int order = 0;
+
+ /**
+ * 是否忽略验证,业务参数验证除外
+ */
+ private boolean ignoreValidate;
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java
index cbb100a1..6466edf5 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java
@@ -32,7 +32,7 @@ public class SopConstants {
public static final int BIZ_ERROR_STATUS = 4000;
/**
- * zookeeper存放接口信息的根目录
+ * zookeeper存放接口路由信息的根目录
*/
- public static final String SOP_SERVICE_API_PATH = "/sop-service-api";
+ public static final String SOP_SERVICE_ROUTE_PATH = "/sop-service-route";
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenResultExecutor.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenResultExecutor.java
new file mode 100644
index 00000000..2f1a2eac
--- /dev/null
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenResultExecutor.java
@@ -0,0 +1,27 @@
+package com.gitee.sop.gatewaycommon.easyopen;
+
+import com.alibaba.fastjson.JSON;
+import com.gitee.sop.gatewaycommon.message.Error;
+import com.gitee.sop.gatewaycommon.result.ApiResult;
+import com.gitee.sop.gatewaycommon.result.ResultExecutor;
+import com.gitee.sop.gatewaycommon.zuul.result.ZuulResultExecutor;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ * @author tanghc
+ */
+public class EasyopenResultExecutor implements ResultExecutor {
+ @Override
+ public String mergeResult(RequestContext request, String serviceResult) {
+ return serviceResult;
+ }
+
+ @Override
+ public String buildErrorResult(RequestContext request, Throwable ex) {
+ ApiResult apiResult = new ApiResult();
+ Error error = ZuulResultExecutor.getError(ex);
+ apiResult.setCode(error.getSub_code());
+ apiResult.setMsg(error.getSub_msg());
+ return JSON.toJSONString(apiResult);
+ }
+}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenSigner.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenSigner.java
new file mode 100644
index 00000000..d77eb6cd
--- /dev/null
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenSigner.java
@@ -0,0 +1,34 @@
+package com.gitee.sop.gatewaycommon.easyopen;
+
+import com.gitee.sop.gatewaycommon.param.ApiParam;
+import com.gitee.sop.gatewaycommon.validate.AbstractSigner;
+import com.gitee.sop.gatewaycommon.validate.taobao.TaobaoSigner;
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author tanghc
+ */
+public class EasyopenSigner extends AbstractSigner {
+ @Override
+ protected String buildServerSign(ApiParam params, String secret) {
+ Set keySet = params.keySet();
+ List paramNames = new ArrayList(keySet);
+
+ Collections.sort(paramNames);
+
+ StringBuilder paramNameValue = new StringBuilder();
+
+ for (String paramName : paramNames) {
+ paramNameValue.append(paramName).append(params.get(paramName));
+ }
+
+ String source = secret + paramNameValue.toString() + secret;
+
+ return DigestUtils.md5Hex(source).toUpperCase();
+ }
+}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenZuulConfiguration.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenZuulConfiguration.java
new file mode 100644
index 00000000..cc8741eb
--- /dev/null
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/easyopen/EasyopenZuulConfiguration.java
@@ -0,0 +1,26 @@
+package com.gitee.sop.gatewaycommon.easyopen;
+
+import com.gitee.sop.gatewaycommon.bean.ApiConfig;
+import com.gitee.sop.gatewaycommon.bean.ApiContext;
+import com.gitee.sop.gatewaycommon.gateway.configuration.BaseGatewayConfiguration;
+import com.gitee.sop.gatewaycommon.param.ParamNames;
+import com.gitee.sop.gatewaycommon.validate.taobao.TaobaoSigner;
+import com.gitee.sop.gatewaycommon.zuul.configuration.BaseZuulConfiguration;
+
+/**
+ * @author tanghc
+ */
+public class EasyopenZuulConfiguration extends BaseZuulConfiguration {
+
+ static {
+ ParamNames.APP_KEY_NAME = "app_key";
+ ParamNames.API_NAME = "name";
+ ParamNames.SIGN_TYPE_NAME = "sign_type";
+ ParamNames.APP_AUTH_TOKEN_NAME = "access_token";
+ ApiConfig apiConfig = ApiContext.getApiConfig();
+ apiConfig.setSigner(new EasyopenSigner());
+ apiConfig.setZuulResultExecutor(new EasyopenResultExecutor());
+ apiConfig.setMergeResult(false);
+ }
+
+}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/param/GatewayParamBuilder.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/param/GatewayParamBuilder.java
index bcd898f0..a0954a2d 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/param/GatewayParamBuilder.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/param/GatewayParamBuilder.java
@@ -2,6 +2,7 @@ package com.gitee.sop.gatewaycommon.gateway.param;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.param.ApiParam;
+import com.gitee.sop.gatewaycommon.param.ApiParamFactory;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
import org.springframework.web.server.ServerWebExchange;
@@ -14,11 +15,7 @@ public class GatewayParamBuilder implements ParamBuilder {
@Override
public ApiParam build(ServerWebExchange exchange) {
Map params = exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP);
- ApiParam apiParam = new ApiParam();
- for (Map.Entry entry : params.entrySet()) {
- apiParam.put(entry.getKey(), entry.getValue());
- }
- return apiParam;
+ return ApiParamFactory.build(params);
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java
index 74c10d73..867c9855 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteManager.java
@@ -16,7 +16,7 @@ import org.springframework.util.StringUtils;
import java.util.List;
-import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_SERVICE_API_PATH;
+import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_SERVICE_ROUTE_PATH;
/**
@@ -30,7 +30,7 @@ import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_SERVICE_API_PATH
@Slf4j
public abstract class BaseRouteManager, E extends BaseRouteDefinition, T> implements RouteManager {
- protected String sopServiceApiPath = SOP_SERVICE_API_PATH;
+ protected String sopServiceApiPath = SOP_SERVICE_ROUTE_PATH;
protected Environment environment;
@@ -93,10 +93,7 @@ public abstract class BaseRouteManager, E exte
String nodeData = new String(childData.getData());
log.info("\t* 子节点路径:" + childData.getPath() + ",该节点的数据为:" + nodeData);
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
- for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
- T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
- routeRepository.add(serviceRouteInfo, routeDefinition);
- }
+ saveRouteDefinitionList(serviceRouteInfo);
}
// 添加事件监听器
childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@@ -110,10 +107,7 @@ public abstract class BaseRouteManager, E exte
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
// 添加子节点时触发
log.info("子节点:{}添加,数据为:{}", event.getData().getPath(), nodeData);
- for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
- T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
- routeRepository.add(serviceRouteInfo, routeDefinition);
- }
+ saveRouteDefinitionList(serviceRouteInfo);
} else if (PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(type)) {
String nodeData = new String(event.getData().getData());
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
@@ -122,20 +116,31 @@ public abstract class BaseRouteManager, E exte
// 删除下面所有节点
routeRepository.deleteAll(serviceRouteInfo);
// 添加新节点
- for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
- T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
- routeRepository.add(serviceRouteInfo, routeDefinition);
- }
+ saveRouteDefinitionList(serviceRouteInfo);
} else if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(type)) {
String nodeData = new String(event.getData().getData());
log.info("子节点:{}删除,数据为:{}", event.getData().getPath(), nodeData);
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
- routeRepository.deleteAll(serviceRouteInfo);
+ deleteRouteDefinitionList(serviceRouteInfo);
}
}
}
});
}
+ protected void saveRouteDefinitionList(R serviceRouteInfo) {
+ for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
+ RouteDefinitionItemContext.add(routeDefinitionItem);
+ T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
+ routeRepository.add(serviceRouteInfo, routeDefinition);
+ }
+ }
+
+ protected void deleteRouteDefinitionList(R serviceRouteInfo) {
+ for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
+ RouteDefinitionItemContext.delete(routeDefinitionItem);
+ }
+ routeRepository.deleteAll(serviceRouteInfo);
+ }
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteDefinitionItemContext.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteDefinitionItemContext.java
new file mode 100644
index 00000000..5e8802f0
--- /dev/null
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/RouteDefinitionItemContext.java
@@ -0,0 +1,27 @@
+package com.gitee.sop.gatewaycommon.manager;
+
+import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author tanghc
+ */
+public class RouteDefinitionItemContext {
+ // key:id
+ private static Map routeDefinitionMap = new HashMap<>(64);
+
+ public static void add(BaseRouteDefinition routeDefinition) {
+ routeDefinitionMap.put(routeDefinition.getId(), routeDefinition);
+ }
+
+ public static BaseRouteDefinition getRouteDefinition(String id) {
+ return routeDefinitionMap.get(id);
+ }
+
+ public static void delete(BaseRouteDefinition routeDefinition) {
+ routeDefinitionMap.remove(routeDefinition.getId());
+ }
+
+}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParamFactory.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParamFactory.java
new file mode 100644
index 00000000..8ecea4ef
--- /dev/null
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParamFactory.java
@@ -0,0 +1,25 @@
+package com.gitee.sop.gatewaycommon.param;
+
+import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
+import com.gitee.sop.gatewaycommon.manager.RouteDefinitionItemContext;
+import com.gitee.sop.gatewaycommon.message.ErrorEnum;
+
+import java.util.Map;
+
+/**
+ * @author tanghc
+ */
+public class ApiParamFactory {
+ public static ApiParam build(Map params) {
+ ApiParam apiParam = new ApiParam();
+ for (Map.Entry entry : params.entrySet()) {
+ apiParam.put(entry.getKey(), entry.getValue());
+ }
+ BaseRouteDefinition routeDefinition = RouteDefinitionItemContext.getRouteDefinition(apiParam.fetchNameVersion());
+ if (routeDefinition == null) {
+ throw ErrorEnum.ISV_INVALID_METHOD.getErrorMeta().getException();
+ }
+ apiParam.setIgnoreValidate(routeDefinition.isIgnoreValidate());
+ return apiParam;
+ }
+}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java
index fc619085..26ed6030 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java
@@ -2,10 +2,14 @@ package com.gitee.sop.gatewaycommon.result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
+import com.gitee.sop.gatewaycommon.exception.ApiException;
+import com.gitee.sop.gatewaycommon.message.Error;
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.message.ErrorMeta;
import com.gitee.sop.gatewaycommon.param.ParamNames;
+import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
@@ -45,6 +49,10 @@ public abstract class BaseExecutorAdapter implements ResultExecutor
@Override
public String mergeResult(T request, String serviceResult) {
+ boolean isMergeResult = ApiContext.getApiConfig().isMergeResult();
+ if (!isMergeResult) {
+ return serviceResult;
+ }
serviceResult = wrapResult(serviceResult);
int responseStatus = this.getBizHeaderCode(request);
JSONObject jsonObjectService;
@@ -99,4 +107,5 @@ public abstract class BaseExecutorAdapter implements ResultExecutor
ret.put(ParamNames.SIGN_NAME, sign);
return ret.toJSONString();
}
+
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java
index b265a60f..f7a264df 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/ResultExecutor.java
@@ -37,7 +37,7 @@ public interface ResultExecutor {
* 合并结果
* @param request
* @param serviceResult
- * @return
+ * @return 返回最终输出结果
*/
String mergeResult(T request, String serviceResult);
@@ -45,7 +45,7 @@ public interface ResultExecutor {
* 合并错误结果
* @param request
* @param ex
- * @return
+ * @return 返回最终输出结果
*/
R buildErrorResult(T request, Throwable ex);
}
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PostResultFilter.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PostResultFilter.java
index 248b9b11..bafb3767 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PostResultFilter.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PostResultFilter.java
@@ -30,6 +30,9 @@ public class PostResultFilter extends BaseZuulFilter {
@Override
protected Object doRun(RequestContext requestContext) throws ZuulException {
+ if (requestContext.getResponse().isCommitted()) {
+ return null;
+ }
InputStream responseDataStream = requestContext.getResponseDataStream();
ApiConfig apiConfig = ApiContext.getApiConfig();
ResultExecutor resultExecutor = apiConfig.getZuulResultExecutor();
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
index ceec5e90..374c9652 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
@@ -2,10 +2,13 @@ package com.gitee.sop.gatewaycommon.zuul.filter;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
+import com.gitee.sop.gatewaycommon.bean.BaseRouteDefinition;
import com.gitee.sop.gatewaycommon.exception.ApiException;
+import com.gitee.sop.gatewaycommon.manager.RouteDefinitionItemContext;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.validate.Validator;
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
+import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteDefinition;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java
index 87710181..a4e1556a 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java
@@ -1,14 +1,17 @@
package com.gitee.sop.gatewaycommon.zuul.param;
import com.alibaba.fastjson.JSON;
+import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.param.ApiParam;
+import com.gitee.sop.gatewaycommon.param.ApiParamFactory;
import com.gitee.sop.gatewaycommon.param.ApiUploadContext;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
import com.gitee.sop.gatewaycommon.util.RequestUtil;
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@@ -24,6 +27,7 @@ import java.util.Set;
*
* @author tanghc
*/
+@Slf4j
public class ZuulParamBuilder implements ParamBuilder {
private static final String CONTENT_TYPE_MULTIPART = MediaType.MULTIPART_FORM_DATA_VALUE;
@@ -33,16 +37,12 @@ public class ZuulParamBuilder implements ParamBuilder {
@Override
public ApiParam build(RequestContext ctx) {
- try {
- HttpServletRequest request = ctx.getRequest();
- Map params = this.getJson(request);
- return new ApiParam(params);
- } catch (Exception e) {
- throw ErrorEnum.ISV_INVALID_PARAMETER.getErrorMeta().getException();
- }
+ HttpServletRequest request = ctx.getRequest();
+ Map params = this.getParams(request);
+ return ApiParamFactory.build(params);
}
- public Map getJson(HttpServletRequest request) throws Exception {
+ public Map getParams(HttpServletRequest request) {
// zuul会做一层包装
if (request instanceof HttpServletRequestWrapper) {
HttpServletRequestWrapper req = (HttpServletRequestWrapper) request;
@@ -63,7 +63,12 @@ public class ZuulParamBuilder implements ParamBuilder {
// json或者纯文本形式
if (contectType.contains(CONTENT_TYPE_JSON) || contectType.contains(CONTENT_TYPE_TEXT)) {
- String txt = RequestUtil.getText(request);
+ String txt = SopConstants.EMPTY_JSON;
+ try {
+ txt = RequestUtil.getText(request);
+ } catch (Exception e) {
+ log.error("获取纯文本内容失败", e);
+ }
params = JSON.parseObject(txt);
} else if (contectType.contains(CONTENT_TYPE_MULTIPART)) {
// 上传文件形式
diff --git a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
index f27805dd..753782fc 100644
--- a/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
+++ b/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/result/ZuulResultExecutor.java
@@ -40,6 +40,12 @@ public class ZuulResultExecutor extends BaseExecutorAdapterorg.springframework.boot
spring-boot-starter-webflux
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
-->
diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java
index 44b3818b..2bc294ba 100644
--- a/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java
+++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/config/ZuulConfig.java
@@ -1,6 +1,7 @@
package com.gitee.sop.gateway.config;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
+import com.gitee.sop.gatewaycommon.easyopen.EasyopenZuulConfiguration;
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
import com.gitee.sop.gatewaycommon.zuul.configuration.TaobaoZuulConfiguration;
import org.springframework.context.annotation.Configuration;
@@ -42,4 +43,14 @@ public class ZuulConfig extends AlipayZuulConfiguration {
// }
//}
-
+/**
+ * 对接easyopen
+ */
+//@Configuration
+//public class ZuulConfig extends EasyopenZuulConfiguration {
+// {
+// Map appSecretStore = new HashMap();
+// appSecretStore.put("easyopen_test", "G9w0BAQEFAAOCAQ8AMIIBCgKCA");
+// ApiContext.getApiConfig().addAppSecret(appSecretStore);
+// }
+//}
diff --git a/sop-service-common/pom.xml b/sop-service-common/pom.xml
index 3d6f1341..0a3a3b0a 100644
--- a/sop-service-common/pom.xml
+++ b/sop-service-common/pom.xml
@@ -3,27 +3,53 @@
4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 2.1.2.RELEASE
-
-
com.gitee.sop
sop-service-common
sop-service-common
1.0.0-SNAPSHOT
+ jar
+ 1.8
UTF-8
Greenwich.RELEASE
+ 2.1.2.RELEASE
1.8
1.8
- 1.8.8.RELEASE
1.2.15
+ 3.4.12
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
com.alibaba
fastjson
@@ -49,7 +75,7 @@
org.apache.zookeeper
zookeeper
- 3.4.12
+ ${zookeeper.version}
org.slf4j
@@ -59,26 +85,25 @@
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
+ net.oschina.durcframework
+ easyopen
+ 1.16.0
+ true
-
- org.apache.tomcat.embed
- tomcat-embed-core
- 9.0.14
- provided
-
+
org.projectlombok
lombok
1.18.4
provided
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ provided
+
junit
@@ -89,23 +114,55 @@
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
-
+
- org.springframework.boot
- spring-boot-maven-plugin
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9
+
+
+ attach-javadocs
+
+ jar
+
+
+
+ -Xdoclint:none
+
+
+
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java
index 91f2af05..07c5ba8c 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiAbility.java
@@ -20,4 +20,9 @@ public @interface ApiAbility {
* 版本号,如:1.0
*/
String version() default "";
+
+ /**
+ * 忽略验证,业务参数除外
+ */
+ boolean ignoreValidate() default false;
}
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java
index 5a5a16d0..b728f9ce 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java
@@ -27,6 +27,11 @@ public @interface ApiMapping {
*/
String version() default "";
+ /**
+ * 忽略验证,业务参数除外
+ */
+ boolean ignoreValidate() default false;
+
/**
* 接口名
* Alias for {@link RequestMapping#value}.
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java
index 3eb368f1..78ceca92 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceApiInfo.java
@@ -24,6 +24,8 @@ public class ServiceApiInfo {
private String path;
/** 版本号 */
private String version;
+ /** 是否忽略验证 */
+ private boolean ignoreValidate;
public ApiMeta() {
}
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceConfig.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceConfig.java
index a6292458..0d929ce9 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceConfig.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/ServiceConfig.java
@@ -47,6 +47,11 @@ public class ServiceConfig {
*/
private GlobalExceptionHandler globalExceptionHandler = new DefaultGlobalExceptionHandler();
+ /**
+ * 设置为true,所有接口不进行校验
+ */
+ private boolean ignoreValidate;
+
public static ServiceConfig getInstance() {
return instance;
}
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java
index f8eba85a..72ce4e96 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java
@@ -4,6 +4,7 @@ import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.interceptor.ServiceContextInterceptor;
import com.gitee.sop.servercommon.manager.ApiMetaManager;
import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent;
+import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import com.gitee.sop.servercommon.message.ServiceErrorFactory;
@@ -41,11 +42,19 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport {
*/
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
- ApiMetaManager apiMetaManager = new ServiceZookeeperApiMetaManager(environment);
- DefaultRequestMappingEvent requestMappingEvent = new DefaultRequestMappingEvent(apiMetaManager, environment);
+ ApiMetaManager apiMetaManager = getApiMetaManager(environment);
+ RequestMappingEvent requestMappingEvent = getRequestMappingEvent(apiMetaManager, environment);
return new ApiMappingHandlerMapping(requestMappingEvent);
}
+ protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) {
+ return new DefaultRequestMappingEvent(apiMetaManager, environment);
+ }
+
+ protected ApiMetaManager getApiMetaManager(Environment environment) {
+ return new ServiceZookeeperApiMetaManager(environment);
+ }
+
@Bean
GlobalExceptionHandler globalExceptionHandler() {
return ServiceConfig.getInstance().getGlobalExceptionHandler();
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java
new file mode 100644
index 00000000..090afcde
--- /dev/null
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java
@@ -0,0 +1,102 @@
+package com.gitee.sop.servercommon.configuration;
+
+import com.gitee.easyopen.ApiContext;
+import com.gitee.easyopen.annotation.Api;
+import com.gitee.easyopen.annotation.ApiService;
+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 com.gitee.sop.servercommon.manager.RequestMappingEvent;
+import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.env.Environment;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+/**
+ * 提供给easyopen项目使用
+ * @author tanghc
+ */
+public class EasyopenServiceConfiguration extends BaseServiceConfiguration {
+
+ @Override
+ protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) {
+ return new EasyopenRequestMappingEvent(apiMetaManager, environment);
+ }
+
+ class EasyopenRequestMappingEvent extends DefaultRequestMappingEvent {
+ String prefixPath;
+
+ public EasyopenRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) {
+ super(apiMetaManager, environment);
+
+ String prefixPath = getEnvironment().getProperty("easyopen.prefix-path");
+ if (prefixPath == null) {
+ throw new IllegalArgumentException("请在application.propertis中设置easyopen.prefix-path属性,填IndexController上面的@RequestMapping()中的值");
+ }
+ this.prefixPath = prefixPath;
+ }
+
+ @Override
+ protected List buildApiMetaList(ApiMappingHandlerMapping apiMappingHandlerMapping) {
+ 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(api.ignoreValidate());
+ // /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;
+ }
+ }
+
+ @Override
+ public void after() {
+ super.after();
+ // 取消验证
+ // todo:需要在easyopen端修改
+ //ApiContext.getApiConfig().setIgnoreValidate(true);
+ }
+}
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java
index 06d29b3f..51c9394e 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java
@@ -35,38 +35,11 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent {
@Override
public void onRegisterSuccess(ApiMappingHandlerMapping apiMappingHandlerMapping) {
- Map handlerMethods = apiMappingHandlerMapping.getHandlerMethods();
- Set requestMappingInfos = handlerMethods.keySet();
- List store = new ArrayList<>(requestMappingInfos.size());
- List apis = new ArrayList<>(requestMappingInfos.size());
-
- for (RequestMappingInfo requestMappingInfo : requestMappingInfos) {
- Set patterns = requestMappingInfo.getPatternsCondition().getPatterns();
- RequestCondition> customCondition = requestMappingInfo.getCustomCondition();
- if (customCondition instanceof ApiMappingRequestCondition) {
- ApiMappingRequestCondition condition = (ApiMappingRequestCondition) customCondition;
- ApiMappingInfo apiMappingInfo = condition.getApiMappingInfo();
- String name = apiMappingInfo.getName();
- String version = apiMappingInfo.getVersion();
- String path = patterns.iterator().next();
- // 不是ApiMapping注解的接口,name属性是null
- if (name == null) {
- name = buildName(path);
- }
- String key = path + version;
- if (store.contains(key)) {
- throw new RuntimeException("重复申明接口,请检查path和version,path:" + path + ", version:" + version);
- } else {
- store.add(key);
- }
- apis.add(new ServiceApiInfo.ApiMeta(name, path, version));
- }
- }
-
String appName = environment.getProperty("spring.application.name");
if (appName == null) {
throw new RuntimeException("请在application.properties中指定spring.application.name属性");
}
+ List apis = this.buildApiMetaList(apiMappingHandlerMapping);
// 排序
Collections.sort(apis, new Comparator() {
@Override
@@ -83,6 +56,49 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent {
apiMetaManager.uploadApi(serviceApiInfo);
}
+ protected List buildApiMetaList(ApiMappingHandlerMapping apiMappingHandlerMapping) {
+ Map handlerMethods = apiMappingHandlerMapping.getHandlerMethods();
+ Set requestMappingInfos = handlerMethods.keySet();
+ List store = new ArrayList<>();
+ List apis = new ArrayList<>(requestMappingInfos.size());
+
+ for (Map.Entry handlerMethodEntry : handlerMethods.entrySet()) {
+ ServiceApiInfo.ApiMeta apiMeta = this.buildApiMeta(handlerMethodEntry);
+ if (apiMeta == null) {
+ continue;
+ }
+ String key = apiMeta.fetchNameVersion();
+ if (store.contains(key)) {
+ throw new RuntimeException("重复申明接口,请检查path和version,path:" + apiMeta.getPath() + ", version:" + apiMeta.getVersion());
+ } else {
+ store.add(key);
+ }
+ apis.add(apiMeta);
+ }
+ return apis;
+ }
+
+ protected ServiceApiInfo.ApiMeta buildApiMeta(Map.Entry handlerMethodEntry) {
+ RequestMappingInfo requestMappingInfo = handlerMethodEntry.getKey();
+ Set patterns = requestMappingInfo.getPatternsCondition().getPatterns();
+ RequestCondition> customCondition = requestMappingInfo.getCustomCondition();
+ if (customCondition instanceof ApiMappingRequestCondition) {
+ ApiMappingRequestCondition condition = (ApiMappingRequestCondition) customCondition;
+ ApiMappingInfo apiMappingInfo = condition.getApiMappingInfo();
+ String name = apiMappingInfo.getName();
+ String version = apiMappingInfo.getVersion();
+ String path = patterns.iterator().next();
+ // 不是ApiMapping注解的接口,name属性是null
+ if (name == null) {
+ name = buildName(path);
+ }
+ ServiceApiInfo.ApiMeta apiMeta = new ServiceApiInfo.ApiMeta(name, path, version);
+ apiMeta.setIgnoreValidate(apiMappingInfo.isIgnoreValidate());
+ return apiMeta;
+ }
+ return null;
+ }
+
protected String buildName(String path) {
path = StringUtils.trimLeadingCharacter(path, '/');
path = StringUtils.trimTrailingCharacter(path, '/');
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java
index 06379318..6788c619 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/ServiceZookeeperApiMetaManager.java
@@ -27,6 +27,11 @@ import java.util.List;
@Setter
public class ServiceZookeeperApiMetaManager implements ApiMetaManager {
+ /**
+ * zookeeper存放接口路由信息的根目录
+ */
+ public static final String SOP_SERVICE_ROUTE_PATH = "/sop-service-route";
+ public static final String PATH_START_CHAR = "/";
/**
* NameVersion=alipay.story.get1.0
@@ -36,8 +41,6 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager {
private static ServiceApiInfo.ApiMeta FIRST_API_META = new ServiceApiInfo.ApiMeta("_" + System.currentTimeMillis() + "_", "/", "0.0");
- private String sopServiceApiPath = "/sop-service-api";
-
private Environment environment;
public ServiceZookeeperApiMetaManager(Environment environment) {
@@ -97,11 +100,27 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager {
List predicates = Arrays.asList(this.buildNameVersionPredicateDefinition(apiMeta));
gatewayRouteDefinition.setPredicates(predicates);
// lb://story-service#/alipay.story.get/
- String servletPath = "#" + apiMeta.getPath();
- gatewayRouteDefinition.setUri("lb://" + serviceApiInfo.getAppName() + servletPath);
+ String uri = this.buildUri(serviceApiInfo, apiMeta);
+ gatewayRouteDefinition.setUri(uri);
+ gatewayRouteDefinition.setIgnoreValidate(apiMeta.isIgnoreValidate());
return gatewayRouteDefinition;
}
+ protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
+ String servletPath = getServletPath(serviceApiInfo, apiMeta);
+ if (servletPath == null) {
+ servletPath = PATH_START_CHAR;
+ }
+ if (!servletPath.startsWith(PATH_START_CHAR)) {
+ servletPath = PATH_START_CHAR + servletPath;
+ }
+ return "lb://" + serviceApiInfo.getAppName() + "#" + servletPath;
+ }
+
+ protected String getServletPath(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
+ return apiMeta.getPath();
+ }
+
protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) {
return new GatewayPredicateDefinition(String.format(QUERY_PREDICATE_DEFINITION_TPL, apiMeta.fetchNameVersion()));
}
@@ -120,7 +139,7 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager {
CuratorFramework client = null;
try {
// 保存路径
- String savePath = sopServiceApiPath + "/" + serviceRouteInfo.getAppName();
+ String savePath = SOP_SERVICE_ROUTE_PATH + "/" + serviceRouteInfo.getAppName();
client = CuratorFrameworkFactory.builder()
.connectString(zookeeperServerAddr)
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java
index 1c2b9c66..733fe290 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java
@@ -3,6 +3,7 @@ package com.gitee.sop.servercommon.mapping;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.bean.ServiceConfig;
+import com.gitee.sop.servercommon.bean.ServiceContext;
import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationUtils;
@@ -42,14 +43,17 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple
method.setAccessible(true);
String name = null;
String version;
+ boolean ignoreValidate = false;
ApiMapping apiMapping = method.getAnnotation(ApiMapping.class);
if (apiMapping != null) {
name = apiMapping.value()[0];
version = apiMapping.version();
+ ignoreValidate = apiMapping.ignoreValidate();
} else {
ApiAbility apiAbility = this.findApiAbilityAnnotation(method);
if (apiAbility != null) {
version = apiAbility.version();
+ ignoreValidate = apiAbility.ignoreValidate();
} else {
return super.getCustomMethodCondition(method);
}
@@ -58,6 +62,11 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple
version = ServiceConfig.getInstance().getDefaultVersion();
}
ApiMappingInfo apiMappingInfo = new ApiMappingInfo(name, version);
+ // 如果是默认配置,则采用全局配置
+ if (!ignoreValidate) {
+ ignoreValidate = ServiceConfig.getInstance().isIgnoreValidate();
+ }
+ apiMappingInfo.setIgnoreValidate(ignoreValidate);
logger.info("注册接口,method:" + method + ", version:" + version);
return new ApiMappingRequestCondition(apiMappingInfo);
}
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java
index 3f14ba6c..79da7a65 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingInfo.java
@@ -9,6 +9,7 @@ import lombok.Data;
public class ApiMappingInfo {
private String name;
private String version;
+ private boolean ignoreValidate;
public ApiMappingInfo(String name, String version) {
this.name = name;
diff --git a/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/GatewayRouteDefinition.java b/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/GatewayRouteDefinition.java
index 6227c95f..5d70d1be 100644
--- a/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/GatewayRouteDefinition.java
+++ b/sop-service-common/src/main/java/com/gitee/sop/servercommon/route/GatewayRouteDefinition.java
@@ -20,4 +20,6 @@ public class GatewayRouteDefinition {
private String uri;
/** 路由执行的顺序 */
private int order = 0;
+ /** 是否忽略验证,业务参数验证除外 */
+ private boolean ignoreValidate;
}
\ No newline at end of file
diff --git a/sop-test/src/test/java/com/gitee/sop/EasyopenClientPostTest.java b/sop-test/src/test/java/com/gitee/sop/EasyopenClientPostTest.java
new file mode 100644
index 00000000..a1445034
--- /dev/null
+++ b/sop-test/src/test/java/com/gitee/sop/EasyopenClientPostTest.java
@@ -0,0 +1,93 @@
+package com.gitee.sop;
+
+import com.alibaba.fastjson.JSON;
+import junit.framework.TestCase;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author tanghc
+ */
+public class EasyopenClientPostTest extends TestBase {
+
+ String url = "http://localhost:8081/api";
+ String appKey = "easyopen_test";
+ String secret = "G9w0BAQEFAAOCAQ8AMIIBCgKCA";
+
+ @Test
+ public void testPost() throws IOException {
+ // 业务参数
+ Map bizParams = new HashMap();
+ bizParams.put("goods_name", "iphoneX");
+
+ String json = JSON.toJSONString(bizParams);
+ json = URLEncoder.encode(json, "utf-8");
+
+ // 系统参数
+ Map params = new HashMap<>();
+ params.put("name", "goods.get");
+ params.put("app_key", appKey);
+ params.put("data", json);
+ params.put("timestamp", getTime());
+ params.put("version", "");
+
+ String sign = buildSign(params, secret);
+
+ params.put("sign", sign);
+
+ System.out.println("=====请求数据=====");
+ System.out.println(JSON.toJSONString(params));
+ System.out.println("=====返回结果=====");
+ String resp = post(url, params);
+ System.out.println(resp);
+ }
+
+ /**
+ * 构建签名串
+ * @param paramsMap 请求参数
+ * @param secret 秘钥
+ * @return
+ * @throws IOException
+ */
+ public String buildSign(Map paramsMap, String secret) throws IOException {
+ Set keySet = paramsMap.keySet();
+ List paramNames = new ArrayList(keySet);
+
+ Collections.sort(paramNames);
+
+ StringBuilder paramNameValue = new StringBuilder();
+
+ for (String paramName : paramNames) {
+ paramNameValue.append(paramName).append(paramsMap.get(paramName));
+ }
+
+ String source = secret + paramNameValue.toString() + secret;
+
+ return md5(source);
+ }
+
+ /**
+ * 生成md5,全部大写。
+ *
+ * @param source
+ * @return
+ */
+ public static String md5(String source) {
+ return DigestUtils.md5Hex(source).toUpperCase();
+ }
+
+ public String getTime() {
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+ }
+}