parent
3bfc5f7cc8
commit
99d90d60cc
@ -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<RequestContext, String> { |
||||
@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); |
||||
} |
||||
} |
@ -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<String> keySet = params.keySet(); |
||||
List<String> paramNames = new ArrayList<String>(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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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<String, BaseRouteDefinition> 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()); |
||||
} |
||||
|
||||
} |
@ -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<String, ?> params) { |
||||
ApiParam apiParam = new ApiParam(); |
||||
for (Map.Entry<String, ?> 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; |
||||
} |
||||
} |
@ -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<ServiceApiInfo.ApiMeta> buildApiMetaList(ApiMappingHandlerMapping apiMappingHandlerMapping) { |
||||
ApplicationContext ctx = getApplicationContext(); |
||||
String[] apiServiceNames = ReflectionUtil.findApiServiceNames(ctx); |
||||
List<ServiceApiInfo.ApiMeta> 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<Method> 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);
|
||||
} |
||||
} |
@ -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<String, String> bizParams = new HashMap<String, String>(); |
||||
bizParams.put("goods_name", "iphoneX"); |
||||
|
||||
String json = JSON.toJSONString(bizParams); |
||||
json = URLEncoder.encode(json, "utf-8"); |
||||
|
||||
// 系统参数
|
||||
Map<String, String> 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<String, ?> paramsMap, String secret) throws IOException { |
||||
Set<String> keySet = paramsMap.keySet(); |
||||
List<String> paramNames = new ArrayList<String>(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()); |
||||
} |
||||
} |
Loading…
Reference in new issue