diff --git a/sop-admin/sop-admin-frontend/src/api/apiTable.ts b/sop-admin/sop-admin-frontend/src/api/apiTable.ts new file mode 100644 index 00000000..d0a39706 --- /dev/null +++ b/sop-admin/sop-admin-frontend/src/api/apiTable.ts @@ -0,0 +1,56 @@ +import axios from 'axios'; +import qs from 'query-string'; +import type { DescData } from '@arco-design/web-vue/es/descriptions/interface'; + +export interface PolicyRecord { + id: string; + number: number; + name: string; + contentType: 'img' | 'horizontalVideo' | 'verticalVideo'; + filterType: 'artificial' | 'rules'; + count: number; + status: 'online' | 'offline'; + createdTime: string; +} + +export interface PolicyParams extends Partial { + pageIndex: number; + pageSize: number; +} + +export interface PolicyListRes { + list: PolicyRecord[]; + total: number; +} + +export function queryPolicyList(params: PolicyParams) { + return axios.get('/api/page', { + params, + paramsSerializer: (obj) => { + return qs.stringify(obj); + }, + }); +} + +export interface ServiceRecord { + id: number; + title: string; + description: string; + name?: string; + actionType?: string; + icon?: string; + data?: DescData[]; + enable?: boolean; + expires?: boolean; +} +export function queryInspectionList() { + return axios.get('/api/list/quality-inspection'); +} + +export function queryTheServiceList() { + return axios.get('/api/list/the-service'); +} + +export function queryRulesPresetList() { + return axios.get('/api/list/rules-preset'); +} diff --git a/sop-admin/sop-admin-frontend/src/views/api/table/index.vue b/sop-admin/sop-admin-frontend/src/views/api/table/index.vue new file mode 100644 index 00000000..bc25ae7a --- /dev/null +++ b/sop-admin/sop-admin-frontend/src/views/api/table/index.vue @@ -0,0 +1,514 @@ + + + + + + + diff --git a/sop-admin/sop-admin-frontend/src/views/api/table/locale/en-US.ts b/sop-admin/sop-admin-frontend/src/views/api/table/locale/en-US.ts new file mode 100644 index 00000000..c5ac3326 --- /dev/null +++ b/sop-admin/sop-admin-frontend/src/views/api/table/locale/en-US.ts @@ -0,0 +1,44 @@ +export default { + 'menu.list.searchTable': 'Search Table', + 'searchTable.form.number': 'Set Number', + 'searchTable.form.number.placeholder': 'Please enter Set Number', + 'searchTable.form.name': 'Set Name', + 'searchTable.form.name.placeholder': 'Please enter Set Name', + 'searchTable.form.contentType': 'Content Type', + 'searchTable.form.contentType.img': 'image-text', + 'searchTable.form.contentType.horizontalVideo': 'Horizontal short video', + 'searchTable.form.contentType.verticalVideo': 'Vertical short video', + 'searchTable.form.filterType': 'Filter Type', + 'searchTable.form.filterType.artificial': 'artificial', + 'searchTable.form.filterType.rules': 'Rules', + 'searchTable.form.createdTime': 'Create Date', + 'searchTable.form.status': 'Status', + 'searchTable.form.status.online': 'Online', + 'searchTable.form.status.offline': 'Offline', + 'searchTable.form.search': 'Search', + 'searchTable.form.reset': 'Reset', + 'searchTable.form.selectDefault': 'All', + 'searchTable.operation.create': 'Create', + 'searchTable.operation.import': 'Import', + 'searchTable.operation.download': 'Download', + // columns + 'searchTable.columns.index': '#', + 'searchTable.columns.number': 'Set Number', + 'searchTable.columns.name': 'Set Name', + 'searchTable.columns.contentType': 'Content Type', + 'searchTable.columns.filterType': 'Filter Type', + 'searchTable.columns.count': 'Count', + 'searchTable.columns.createdTime': 'CreatedTime', + 'searchTable.columns.status': 'Status', + 'searchTable.columns.operations': 'Operations', + 'searchTable.columns.operations.view': 'View', + // size + 'searchTable.size.mini': 'mini', + 'searchTable.size.small': 'small', + 'searchTable.size.medium': 'middle', + 'searchTable.size.large': 'large', + // actions + 'searchTable.actions.refresh': 'refresh', + 'searchTable.actions.density': 'density', + 'searchTable.actions.columnSetting': 'columnSetting', +}; diff --git a/sop-admin/sop-admin-frontend/src/views/api/table/locale/zh-CN.ts b/sop-admin/sop-admin-frontend/src/views/api/table/locale/zh-CN.ts new file mode 100644 index 00000000..ca4cd442 --- /dev/null +++ b/sop-admin/sop-admin-frontend/src/views/api/table/locale/zh-CN.ts @@ -0,0 +1,45 @@ +export default { + 'menu.list.searchTable': '查询表格', + 'searchTable.form.number': '集合编号', + 'searchTable.form.number.placeholder': '请输入集合编号', + 'searchTable.form.name': '集合名称', + 'searchTable.form.name.placeholder': '请输入集合名称', + 'searchTable.form.contentType': '内容体裁', + 'searchTable.form.contentType.img': '图文', + 'searchTable.form.contentType.horizontalVideo': '横版短视频', + 'searchTable.form.contentType.verticalVideo': '竖版小视频', + 'searchTable.form.filterType': '筛选方式', + 'searchTable.form.filterType.artificial': '人工筛选', + 'searchTable.form.filterType.rules': '规则筛选', + 'searchTable.form.createdTime': '创建时间', + 'searchTable.form.status': '状态', + 'searchTable.form.status.online': '已上线', + 'searchTable.form.status.offline': '已下线', + 'searchTable.form.search': '查询', + 'searchTable.form.reset': '重置', + 'searchTable.form.selectDefault': '全部', + 'searchTable.operation.create': '新建', + 'searchTable.operation.import': '批量导入', + 'searchTable.operation.download': '下载', + // columns + 'searchTable.columns.index': '#', + 'searchTable.columns.number': '集合编号', + 'searchTable.columns.name': '集合名称', + 'searchTable.columns.contentType': '内容体裁', + 'searchTable.columns.filterType': '筛选方式', + 'searchTable.columns.count': '内容量', + 'searchTable.columns.createdTime': '创建时间', + 'searchTable.columns.status': '状态', + 'searchTable.columns.operations': '操作', + 'searchTable.columns.operations.view': '查看', + + // size + 'searchTable.size.mini': '迷你', + 'searchTable.size.small': '偏小', + 'searchTable.size.medium': '中等', + 'searchTable.size.large': '偏大', + // actions + 'searchTable.actions.refresh': '刷新', + 'searchTable.actions.density': '密度', + 'searchTable.actions.columnSetting': '列设置', +}; diff --git a/sop-example/sop-story/pom.xml b/sop-example/sop-story/pom.xml index 0ee5b9e4..4ace5b3a 100644 --- a/sop-example/sop-story/pom.xml +++ b/sop-example/sop-story/pom.xml @@ -36,16 +36,13 @@ org.apache.dubbo dubbo-spring-boot-starter - ${dubbo.version} - - com.alibaba.boot - nacos-discovery-spring-boot-starter - 0.2.1 + org.apache.dubbo + dubbo-nacos-spring-boot-starter - --> org.apache.commons @@ -80,6 +77,18 @@ + + + + org.apache.dubbo + dubbo-bom + ${dubbo.version} + pom + import + + + + diff --git a/sop-example/sop-story/src/main/resources/application-dev.properties b/sop-example/sop-story/src/main/resources/application-dev.properties index ff692cf5..bfead63f 100644 --- a/sop-example/sop-story/src/main/resources/application-dev.properties +++ b/sop-example/sop-story/src/main/resources/application-dev.properties @@ -1,7 +1 @@ -server.port=8082 -spring.application.name=story-service - -dubbo.protocol.name=dubbo -dubbo.protocol.port=-1 -dubbo.application.qos-enable=false dubbo.registry.address=zookeeper://localhost:2181 diff --git a/sop-example/sop-story/src/main/resources/application-test.properties b/sop-example/sop-story/src/main/resources/application-test.properties new file mode 100644 index 00000000..53e5d0bc --- /dev/null +++ b/sop-example/sop-story/src/main/resources/application-test.properties @@ -0,0 +1,2 @@ + +dubbo.registry.address=nacos://localhost:8848 diff --git a/sop-example/sop-story/src/main/resources/application.properties b/sop-example/sop-story/src/main/resources/application.properties index cbb42d2a..b5ae77a1 100644 --- a/sop-example/sop-story/src/main/resources/application.properties +++ b/sop-example/sop-story/src/main/resources/application.properties @@ -1 +1,9 @@ -spring.profiles.active=dev +spring.profiles.active=test + +server.port=8082 +spring.application.name=story-service + +dubbo.protocol.name=dubbo +dubbo.protocol.port=-1 +dubbo.application.qos-enable=false +dubbo.registry.address=zookeeper://localhost:2181 diff --git a/sop-index/pom.xml b/sop-index/pom.xml index 3c111a78..4fecfa33 100644 --- a/sop-index/pom.xml +++ b/sop-index/pom.xml @@ -64,10 +64,10 @@ dubbo-spring-boot-starter + - com.alibaba.boot - nacos-discovery-spring-boot-starter - 0.2.1 + org.apache.dubbo + dubbo-nacos-spring-boot-starter @@ -85,6 +85,12 @@ spring-boot-starter-jdbc + + org.springframework.boot + spring-boot-starter-data-redis + + + commons-codec commons-codec @@ -103,6 +109,13 @@ hibernate-validator + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + org.springframework.boot spring-boot-starter-test @@ -153,14 +166,10 @@ org.apache.dubbo - dubbo-spring-boot-starter + dubbo-bom ${dubbo.version} - - - - com.alibaba.boot - nacos-discovery-spring-boot-starter - 0.2.1 + pom + import diff --git a/sop-index/src/main/java/com/gitee/sop/index/common/SopConstants.java b/sop-index/src/main/java/com/gitee/sop/index/common/SopConstants.java index 5aff57d8..8b5192d2 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/common/SopConstants.java +++ b/sop-index/src/main/java/com/gitee/sop/index/common/SopConstants.java @@ -12,53 +12,5 @@ public class SopConstants { public static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; public static final String UTF8 = "UTF-8"; - public static final String FORMAT_JSON = "json"; - public static final String DEFAULT_SIGN_METHOD = "md5"; - public static final String EMPTY_JSON = "{}"; - - public static final String METADATA_SERVER_CONTEXT_PATH = "server.servlet.context-path"; - - public static final String METADATA_SERVER_CONTEXT_PATH_COMPATIBILITY = "context-path"; - - /** - * 在拦截器中调用获取参数: - * String cachedBody = (String)exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_OBJECT_KEY); - */ - public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject"; - - /** - * 在拦截器中调用获取参数: - * Map params = exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP); - */ - public static final String CACHE_REQUEST_BODY_FOR_MAP = "cacheRequestBodyForMap"; - - public static final String CACHE_API_PARAM = "cacheApiParam"; - - public static final String CACHE_UPLOAD_REQUEST = "cacheUploadRequest"; - - public static final String X_SERVICE_ERROR_CODE = "x-service-error-code"; - - public static final String X_SERVICE_ERROR_MESSAGE = "x-service-error-message"; - - public static final String X_SERVICE_ERROR_RESPONSE = "x-service-error-response"; - - public static final int BIZ_ERROR_STATUS = 4000; - public static final int UNKNOWN_ERROR_STATUS = 5050; - - public static final String UNKNOWN_SERVICE= "_sop_unknown_service_"; - public static final String UNKNOWN_METHOD = "_sop_unknown_method_"; - public static final String UNKNOWN_VERSION = "_sop_unknown_version_"; - - public static final String METADATA_ENV_KEY = "env"; - public static final String METADATA_ENV_PRE_VALUE = "pre"; - public static final String METADATA_ENV_GRAY_VALUE = "gray"; - - public static final String CACHE_ROUTE_INTERCEPTOR_CONTEXT = "cacheRouteInterceptorContext"; - public static final String TARGET_SERVICE = "sop-target-service"; - public static final String RESTFUL_REQUEST = "sop-restful-request"; - - public static final String METADATA_KEY_TIME_STARTUP = "server.startup-time"; - - public static final String CACHE_ROUTE_INFO = "cacheRouteInfo"; } diff --git a/sop-index/src/main/java/com/gitee/sop/index/config/CustomConfig.java b/sop-index/src/main/java/com/gitee/sop/index/config/CustomConfig.java new file mode 100644 index 00000000..75949c66 --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/config/CustomConfig.java @@ -0,0 +1,14 @@ +package com.gitee.sop.index.config; + +import org.springframework.context.annotation.Configuration; + +/** + * 自定的扩展组件放这里 + * + * @author 六如 + */ +@Configuration +public class CustomConfig { + + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/config/IndexConfig.java b/sop-index/src/main/java/com/gitee/sop/index/config/IndexConfig.java index cd2dc828..a2cd0661 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/config/IndexConfig.java +++ b/sop-index/src/main/java/com/gitee/sop/index/config/IndexConfig.java @@ -1,11 +1,18 @@ package com.gitee.sop.index.config; import com.gitee.sop.index.message.ErrorFactory; +import com.gitee.sop.index.service.ParamExecutor; +import com.gitee.sop.index.service.ParamExecutorImpl; +import com.gitee.sop.index.service.RouteService; +import com.gitee.sop.index.service.RouteServiceImpl; import com.gitee.sop.index.service.interceptor.internal.ResultRouteInterceptor; -import com.gitee.sop.index.service.manager.impl.LocalApiCacheManagerImpl; +import com.gitee.sop.index.service.manager.ApiManager; +import com.gitee.sop.index.service.manager.IsvManager; +import com.gitee.sop.index.service.manager.SecretManager; +import com.gitee.sop.index.service.manager.impl.LocalApiManagerImpl; import com.gitee.sop.index.service.manager.impl.LocalIsvManagerImpl; import com.gitee.sop.index.service.manager.impl.LocalSecretManagerImpl; -import com.gitee.sop.index.service.manager.impl.RedisApiCacheManagerImpl; +import com.gitee.sop.index.service.manager.impl.RedisApiManagerImpl; import com.gitee.sop.index.service.manager.impl.RedisIsvManagerImpl; import com.gitee.sop.index.service.manager.impl.RedisSecretManager; import lombok.extern.slf4j.Slf4j; @@ -24,38 +31,38 @@ import javax.annotation.PostConstruct; public class IndexConfig { @Bean - @ConditionalOnProperty(value = "manager.api-cache", havingValue = "local", matchIfMissing = true) - public LocalApiCacheManagerImpl localApiCacheManager() { - return new LocalApiCacheManagerImpl(); + @ConditionalOnProperty(value = "manager.api", havingValue = "local", matchIfMissing = true) + public ApiManager localApiManager() { + return new LocalApiManagerImpl(); } @Bean - @ConditionalOnProperty(value = "manager.api-cache", havingValue = "redis") - public RedisApiCacheManagerImpl redisApiCacheManager() { - return new RedisApiCacheManagerImpl(); + @ConditionalOnProperty(value = "manager.api", havingValue = "redis") + public ApiManager redisApiManager() { + return new RedisApiManagerImpl(); } @Bean @ConditionalOnProperty(value = "manager.isv", havingValue = "local", matchIfMissing = true) - public LocalIsvManagerImpl localIsvManager() { + public IsvManager localIsvManager() { return new LocalIsvManagerImpl(); } @Bean @ConditionalOnProperty(value = "manager.isv", havingValue = "redis") - public RedisIsvManagerImpl redisIsvManager() { + public IsvManager redisIsvManager() { return new RedisIsvManagerImpl(); } @Bean @ConditionalOnProperty(value = "manager.secret", havingValue = "local", matchIfMissing = true) - public LocalSecretManagerImpl localSecretManager() { + public SecretManager localSecretManager() { return new LocalSecretManagerImpl(); } @Bean @ConditionalOnProperty(value = "manager.secret", havingValue = "redis") - public RedisSecretManager redisSecretManager() { + public SecretManager redisSecretManager() { return new RedisSecretManager(); } @@ -67,6 +74,17 @@ public class IndexConfig { return new ResultRouteInterceptor(); } + @Bean + @ConditionalOnMissingBean + public ParamExecutor paramExecutor() { + return new ParamExecutorImpl(); + } + + @Bean + @ConditionalOnMissingBean + public RouteService routeService() { + return new RouteServiceImpl(); + } @PostConstruct public void init() { diff --git a/sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java b/sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java index 3a942369..2fb9371d 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java +++ b/sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java @@ -1,11 +1,10 @@ package com.gitee.sop.index.controller; -import com.gitee.sop.index.response.ApiResponse; import com.gitee.sop.index.request.ApiRequestContext; import com.gitee.sop.index.request.ApiRequestContextFactory; +import com.gitee.sop.index.response.ApiResponse; +import com.gitee.sop.index.service.ParamExecutor; import com.gitee.sop.index.service.RouteService; -import com.gitee.sop.index.util.ResponseUtil; -import com.gitee.sop.support.request.FileData; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -27,28 +26,39 @@ public class IndexController { @Resource private RouteService routeService; + @Resource + private ParamExecutor paramExecutor; + @GetMapping("/") public void home(HttpServletResponse response) throws IOException { response.getWriter().write("Open Platform"); + // 跳转到网站首页 + // response.sendRedirect("https://www.baidu.com"); } /** * 请求入口 * - * @return 返回响应内容 + * @apiNote 参数描述 +
+    参数	            类型	    是否必填	    最大长度	    描述	            示例值
+    app_id	        String	是	        32	    支付宝分配给开发者的应用ID	2014072300007148
+    method	        String	是	        128	    接口名称	alipay.trade.fastpay.refund.query
+    format	        String	否	        40	    仅支持JSON	JSON
+    charset	        String	是	        10	    请求使用的编码格式,如utf-8,gbk,gb2312等	utf-8
+    sign_type	    String	是	        10	    商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2	RSA2
+    sign	        String	是	        344	    商户请求参数的签名串,详见签名	详见示例
+    timestamp	    String	是	        19	    发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"	2014-07-24 03:07:50
+    version	        String	是	        3	    调用的接口版本,固定为:1.0	1.0
+    app_auth_token	String	否	        40	    详见应用授权概述
+    biz_content	    String	是		请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
+    
*/ - @RequestMapping(value = "api", method = {RequestMethod.GET, RequestMethod.POST}) + @RequestMapping(value = "${index.path:/api}", method = {RequestMethod.GET, RequestMethod.POST}) public void index(HttpServletRequest request, HttpServletResponse response) throws IOException { - ApiRequestContext apiRequestContext = ApiRequestContextFactory.build(request); + ApiRequestContext apiRequestContext = paramExecutor.build(request); ApiResponse apiResponse = routeService.route(apiRequestContext); - Object data = apiResponse.getData(); - if (data instanceof FileData) { - FileData fileData = (FileData) data; - ResponseUtil.writerFile(fileData, response); - } else { - // 此处还可以判断charset,返回xml格式 - ResponseUtil.writerJson(apiRequestContext, apiResponse, response); - } + paramExecutor.write(apiRequestContext, apiResponse, response); } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/dao/mapper/IsvKeysMapper.java b/sop-index/src/main/java/com/gitee/sop/index/dao/mapper/IsvKeysMapper.java index 99d169e1..84e32482 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/dao/mapper/IsvKeysMapper.java +++ b/sop-index/src/main/java/com/gitee/sop/index/dao/mapper/IsvKeysMapper.java @@ -8,4 +8,8 @@ import com.gitee.sop.index.dao.entity.IsvKeys; */ public interface IsvKeysMapper extends BaseMapper { + default IsvKeys getByAppId(String appId) { + return this.get(IsvKeys::getAppId, appId); + } + } diff --git a/sop-index/src/main/java/com/gitee/sop/index/request/RequestFormatEnum.java b/sop-index/src/main/java/com/gitee/sop/index/request/RequestFormatEnum.java new file mode 100644 index 00000000..cdb556ab --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/request/RequestFormatEnum.java @@ -0,0 +1,26 @@ +package com.gitee.sop.index.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author 六如 + */ +@Getter +@AllArgsConstructor +public enum RequestFormatEnum { + NONE(""), + JSON("json"), + XML("xml"), + ; + private final String value; + + public static RequestFormatEnum of(String value) { + for (RequestFormatEnum requestFormatEnum : RequestFormatEnum.values()) { + if (requestFormatEnum.value.equalsIgnoreCase(value)) { + return requestFormatEnum; + } + } + return NONE; + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/ApiInfoService.java b/sop-index/src/main/java/com/gitee/sop/index/service/ApiInfoService.java deleted file mode 100644 index 351246d9..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/ApiInfoService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.gitee.sop.index.service; - -import com.gitee.sop.index.common.ApiInfoDTO; -import com.gitee.sop.index.dao.entity.ApiInfo; -import com.gitee.sop.index.dao.mapper.ApiInfoMapper; -import com.gitee.sop.index.service.manager.ApiCacheManager; -import com.gitee.sop.index.util.CopyUtil; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * @author 六如 - */ -@Service -public class ApiInfoService { - - @Resource - private ApiCacheManager apiCacheManager; - - @Resource - private ApiInfoMapper apiInfoMapper; - - public ApiInfoDTO getApi(String apiName, String apiVersion) { - return apiCacheManager.getOrElse(apiName, apiVersion, () -> { - ApiInfo apiInfo = apiInfoMapper.getByNameVersion(apiName, apiVersion); - return CopyUtil.copyBean(apiInfo, ApiInfoDTO::new); - }); - } - -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutor.java b/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutor.java new file mode 100644 index 00000000..018339b7 --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutor.java @@ -0,0 +1,33 @@ +package com.gitee.sop.index.service; + +import com.gitee.sop.index.request.ApiRequestContext; +import com.gitee.sop.index.response.ApiResponse; + +import java.io.IOException; + +/** + * 参数处理 + * + * @author 六如 + */ +public interface ParamExecutor { + + /** + * 构建请求参数上下文 + * + * @param request request + * @return 返回请求参数上下文 + */ + ApiRequestContext build(Req request); + + /** + * 结果返回写入 + * + * @param apiRequestContext 请求参数上下文 + * @param apiResponse 最终返回结果 + * @param response response + * @throws IOException IOException + */ + void write(ApiRequestContext apiRequestContext, ApiResponse apiResponse, Resp response) throws IOException; + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutorImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutorImpl.java new file mode 100644 index 00000000..3c08cdff --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/service/ParamExecutorImpl.java @@ -0,0 +1,36 @@ +package com.gitee.sop.index.service; + +import com.gitee.sop.index.request.ApiRequestContext; +import com.gitee.sop.index.request.ApiRequestContextFactory; +import com.gitee.sop.index.response.ApiResponse; +import com.gitee.sop.index.util.ResponseUtil; +import com.gitee.sop.support.request.FileData; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 请求参数默认实现 + * + * @author 六如 + */ +public class ParamExecutorImpl implements ParamExecutor { + + @Override + public ApiRequestContext build(HttpServletRequest request) { + return ApiRequestContextFactory.build(request); + } + + @Override + public void write(ApiRequestContext apiRequestContext, ApiResponse apiResponse, HttpServletResponse response) throws IOException { + Object data = apiResponse.getData(); + if (data instanceof FileData) { + FileData fileData = (FileData) data; + ResponseUtil.writerFile(fileData, response); + } else { + // 此处还可以判断charset,返回xml格式 + ResponseUtil.writerText(apiRequestContext, apiResponse, response); + } + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/RouteServiceImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/RouteServiceImpl.java index 9082038c..106655d6 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/RouteServiceImpl.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/RouteServiceImpl.java @@ -3,7 +3,6 @@ package com.gitee.sop.index.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.gitee.sop.index.common.ApiInfoDTO; -import com.gitee.sop.index.response.ApiResponse; import com.gitee.sop.index.common.AttachmentNames; import com.gitee.sop.index.common.ParamInfoDTO; import com.gitee.sop.index.exception.ApiException; @@ -12,6 +11,7 @@ import com.gitee.sop.index.message.ErrorEnum; import com.gitee.sop.index.request.ApiRequest; import com.gitee.sop.index.request.ApiRequestContext; import com.gitee.sop.index.request.UploadContext; +import com.gitee.sop.index.response.ApiResponse; import com.gitee.sop.index.service.interceptor.RouteInterceptor; import com.gitee.sop.index.service.validate.Validator; import com.gitee.sop.index.util.ClassUtil; @@ -22,7 +22,6 @@ import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcContextAttachment; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.springframework.web.multipart.MultipartFile; @@ -34,7 +33,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -44,7 +42,6 @@ import java.util.Optional; * * @author 六如 */ -@Service @Slf4j public class RouteServiceImpl implements RouteService { @@ -204,7 +201,7 @@ public class RouteServiceImpl implements RouteService { @PostConstruct public void init() { if (routeInterceptors == null) { - routeInterceptors = Collections.emptyList(); + routeInterceptors = new ArrayList<>(); } routeInterceptors.sort(Comparator.comparing(RouteInterceptor::getOrder)); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/dubbo/ApiRegisterServiceImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/dubbo/ApiRegisterServiceImpl.java index 67bc9930..c08b5476 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/dubbo/ApiRegisterServiceImpl.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/dubbo/ApiRegisterServiceImpl.java @@ -4,7 +4,7 @@ import com.gitee.sop.index.common.ApiInfoDTO; import com.gitee.sop.index.common.StatusEnum; import com.gitee.sop.index.dao.entity.ApiInfo; import com.gitee.sop.index.dao.mapper.ApiInfoMapper; -import com.gitee.sop.index.service.manager.ApiCacheManager; +import com.gitee.sop.index.service.manager.ApiManager; import com.gitee.sop.index.util.CopyUtil; import com.gitee.sop.support.service.ApiRegisterService; import com.gitee.sop.support.service.dto.RegisterDTO; @@ -21,7 +21,7 @@ import javax.annotation.Resource; public class ApiRegisterServiceImpl implements ApiRegisterService { @Resource - private ApiCacheManager apiCacheManager; + private ApiManager apiCacheManager; @Resource private ApiInfoMapper apiInfoMapper; diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/RouteInterceptorOrders.java b/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/RouteInterceptorOrders.java index 68dc8003..2f2f531a 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/RouteInterceptorOrders.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/RouteInterceptorOrders.java @@ -5,6 +5,6 @@ package com.gitee.sop.index.service.interceptor; */ public class RouteInterceptorOrders { - public static final int DOWNLOAD = -10; + public static final int RESULT_INTERCEPTOR = -1000; } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/internal/ResultRouteInterceptor.java b/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/internal/ResultRouteInterceptor.java index 719575e6..32de003c 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/internal/ResultRouteInterceptor.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/interceptor/internal/ResultRouteInterceptor.java @@ -3,6 +3,7 @@ package com.gitee.sop.index.service.interceptor.internal; import com.gitee.sop.index.common.ApiInfoDTO; import com.gitee.sop.index.request.ApiRequestContext; import com.gitee.sop.index.service.interceptor.RouteInterceptor; +import com.gitee.sop.index.service.interceptor.RouteInterceptorOrders; import com.gitee.sop.support.request.CommonFileData; import com.gitee.sop.support.request.FileData; @@ -19,6 +20,10 @@ import java.util.Objects; public class ResultRouteInterceptor implements RouteInterceptor { private static final String CLASS = "class"; + private static final String KEY_NAME = "name"; + private static final String KEY_ORIGINAL_FILENAME = "originalFilename"; + private static final String KEY_CONTENT_TYPE = "contentType"; + private static final String KEY_BYTES = "bytes"; @Override public Object afterRoute(ApiRequestContext context, ApiInfoDTO apiInfoDTO, Object result) { @@ -44,10 +49,10 @@ public class ResultRouteInterceptor implements RouteInterceptor { "empty": false */ CommonFileData commonFileData = new CommonFileData(); - commonFileData.setName(String.valueOf(map.get("name"))); - commonFileData.setOriginalFilename(String.valueOf(map.get("originalFilename"))); - commonFileData.setContentType(String.valueOf(map.get("contentType"))); - commonFileData.setData((byte[]) map.get("bytes")); + commonFileData.setName(String.valueOf(map.get(KEY_NAME))); + commonFileData.setOriginalFilename(String.valueOf(map.get(KEY_ORIGINAL_FILENAME))); + commonFileData.setContentType(String.valueOf(map.get(KEY_CONTENT_TYPE))); + commonFileData.setData((byte[]) map.get(KEY_BYTES)); return commonFileData; } } @@ -61,6 +66,6 @@ public class ResultRouteInterceptor implements RouteInterceptor { @Override public int getOrder() { - return RouteInterceptor.super.getOrder(); + return RouteInterceptorOrders.RESULT_INTERCEPTOR; } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiManager.java similarity index 94% rename from sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java rename to sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiManager.java index 77947780..c67ce506 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/ApiManager.java @@ -7,7 +7,7 @@ import java.util.function.Supplier; /** * @author 六如 */ -public interface ApiCacheManager { +public interface ApiManager { void save(ApiInfoDTO apiInfoDTO); diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/IsvManager.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/IsvManager.java index 164900b7..86247bb8 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/IsvManager.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/IsvManager.java @@ -7,7 +7,18 @@ import com.gitee.sop.index.service.manager.dto.IsvDTO; */ public interface IsvManager { + /** + * 获取isv信息 + * + * @param appId appId + * @return 返回isv信息, 没有返回null + */ IsvDTO getIsv(String appId); + /** + * 重新加载isv信息到内存中 + * + * @param appId appId + */ void reload(String appId); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java index e9d05036..876f7f5f 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java @@ -15,5 +15,5 @@ public interface SecretManager { */ String getIsvPublicKey(String appId); - + String reload(String appId); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java deleted file mode 100644 index 3155641a..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.gitee.sop.index.service.manager.impl; - -import com.gitee.sop.index.common.ApiInfoDTO; -import com.gitee.sop.index.service.manager.ApiCacheManager; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 本地存储接口信息. - * @author 六如 - */ -public class LocalApiCacheManagerImpl implements ApiCacheManager { - - private static final Map CACHE = new ConcurrentHashMap<>(); - - @Override - public void save(ApiInfoDTO apiInfoDTO) { - String key = apiInfoDTO.buildApiNameVersion(); - CACHE.put(key, apiInfoDTO); - } - - @Override - public ApiInfoDTO get(String apiName, String apiVersion) { - return CACHE.get(apiName + apiVersion); - } -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiManagerImpl.java new file mode 100644 index 00000000..1442a1ee --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiManagerImpl.java @@ -0,0 +1,39 @@ +package com.gitee.sop.index.service.manager.impl; + +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.dao.entity.ApiInfo; +import com.gitee.sop.index.dao.mapper.ApiInfoMapper; +import com.gitee.sop.index.service.manager.ApiManager; +import com.gitee.sop.index.util.CopyUtil; + +import javax.annotation.Resource; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 本地存储接口信息. + * @author 六如 + */ +public class LocalApiManagerImpl implements ApiManager { + + private static final Map> CACHE = new ConcurrentHashMap<>(); + + @Resource + protected ApiInfoMapper apiInfoMapper; + + @Override + public void save(ApiInfoDTO apiInfoDTO) { + String key = apiInfoDTO.buildApiNameVersion(); + CACHE.put(key, Optional.of(apiInfoDTO)); + } + + @Override + public ApiInfoDTO get(String apiName, String apiVersion) { + String key = apiName + apiVersion; + return CACHE.computeIfAbsent(key, k-> { + ApiInfo apiInfo = apiInfoMapper.getByNameVersion(apiName, apiVersion); + return Optional.ofNullable(CopyUtil.copyBean(apiInfo, ApiInfoDTO::new)); + }).orElse(null); + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalIsvManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalIsvManagerImpl.java index 551547c6..2d80b60c 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalIsvManagerImpl.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalIsvManagerImpl.java @@ -7,23 +7,34 @@ import com.gitee.sop.index.service.manager.dto.IsvDTO; import com.gitee.sop.index.util.CopyUtil; import javax.annotation.Resource; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; /** * @author 六如 */ public class LocalIsvManagerImpl implements IsvManager { + private static final Map> CACHE = new ConcurrentHashMap<>(); + + @Resource - private IsvInfoMapper isvInfoMapper; + protected IsvInfoMapper isvInfoMapper; @Override public IsvDTO getIsv(String appId) { - IsvInfo isvInfo = isvInfoMapper.getByAppId(appId); - return CopyUtil.copyBean(isvInfo, IsvDTO::new); + return CACHE.computeIfAbsent(appId, k -> { + IsvInfo isvInfo = isvInfoMapper.getByAppId(appId); + return Optional.ofNullable(CopyUtil.copyBean(isvInfo, IsvDTO::new)); + }).orElse(null); } @Override public void reload(String appId) { + IsvInfo isvInfo = isvInfoMapper.getByAppId(appId); + IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new); + CACHE.put(appId, Optional.ofNullable(isvDTO)); } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java index 2421df7f..f42b1380 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java @@ -5,19 +5,37 @@ import com.gitee.sop.index.dao.mapper.IsvKeysMapper; import com.gitee.sop.index.service.manager.SecretManager; import javax.annotation.Resource; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; /** * @author 六如 */ public class LocalSecretManagerImpl implements SecretManager { + private static final Map> CACHE = new ConcurrentHashMap<>(); + @Resource - private IsvKeysMapper isvKeysMapper; + protected IsvKeysMapper isvKeysMapper; @Override public String getIsvPublicKey(String appId) { - return isvKeysMapper.query() + return CACHE.computeIfAbsent(appId, k -> { + String publicKey = isvKeysMapper.query() + .eq(IsvKeys::getAppId, appId) + .getValue(IsvKeys::getPublicKeyIsv); + return Optional.ofNullable(publicKey); + }) + .orElse(null); + } + + @Override + public String reload(String appId) { + String publicKey = isvKeysMapper.query() .eq(IsvKeys::getAppId, appId) .getValue(IsvKeys::getPublicKeyIsv); + CACHE.put(appId, Optional.ofNullable(publicKey)); + return publicKey; } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java deleted file mode 100644 index ff72fcb1..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.sop.index.service.manager.impl; - -import com.gitee.sop.index.common.ApiInfoDTO; -import com.gitee.sop.index.service.manager.ApiCacheManager; - -/** - * redis存储接口信息 - * - * @author 六如 - */ -public class RedisApiCacheManagerImpl implements ApiCacheManager { - - - - @Override - public void save(ApiInfoDTO apiInfoDTO) { - - } - - @Override - public ApiInfoDTO get(String apiName, String apiVersion) { - return null; - } -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiManagerImpl.java new file mode 100644 index 00000000..753252e8 --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiManagerImpl.java @@ -0,0 +1,62 @@ +package com.gitee.sop.index.service.manager.impl; + +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.dao.entity.ApiInfo; +import com.gitee.sop.index.util.CopyUtil; +import com.gitee.sop.index.util.JsonUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; + +/** + * redis存储接口信息 + * + * @author 六如 + */ +@Slf4j +public class RedisApiManagerImpl extends LocalApiManagerImpl { + + private static final String KEY_API = "sop:api"; + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Override + public void save(ApiInfoDTO apiInfoDTO) { + String key = apiInfoDTO.buildApiNameVersion(); + stringRedisTemplate.opsForHash().put(KEY_API, key, JsonUtil.toJSONString(apiInfoDTO)); + } + + protected void cache(String key, ApiInfo apiInfo) { + ApiInfoDTO apiInfoDTO = CopyUtil.copyBean(apiInfo, ApiInfoDTO::new); + stringRedisTemplate.opsForHash().put(KEY_API, key, JsonUtil.toJSONString(apiInfoDTO)); + } + + @Override + public ApiInfoDTO get(String apiName, String apiVersion) { + String key = apiName + apiName; + try { + Object value = stringRedisTemplate.opsForHash().get(KEY_API, key); + if (value == null) { + return null; + } + return JsonUtil.parseObject(String.valueOf(value), ApiInfoDTO.class); + } catch (Exception e) { + log.error("redis访问失败", e); + return super.get(apiName, apiVersion); + } + } + + @PostConstruct + public void init() { + log.info("load apiInfo to redis"); + List apiInfos = this.apiInfoMapper.listAll(); + for (ApiInfo apiInfo : apiInfos) { + String key = apiInfo.getApiName() + apiInfo.getApiVersion(); + this.cache(key, apiInfo); + } + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisIsvManagerImpl.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisIsvManagerImpl.java index 66597825..790e8222 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisIsvManagerImpl.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisIsvManagerImpl.java @@ -1,20 +1,61 @@ package com.gitee.sop.index.service.manager.impl; -import com.gitee.sop.index.service.manager.IsvManager; +import com.gitee.sop.index.dao.entity.IsvInfo; import com.gitee.sop.index.service.manager.dto.IsvDTO; +import com.gitee.sop.index.util.CopyUtil; +import com.gitee.sop.index.util.JsonUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; /** * @author 六如 */ -public class RedisIsvManagerImpl implements IsvManager { +@Slf4j +public class RedisIsvManagerImpl extends LocalIsvManagerImpl { + + private static final String KEY_ISV = "sop:isv"; + + @Resource + private StringRedisTemplate stringRedisTemplate; + @Override public IsvDTO getIsv(String appId) { - return null; + try { + Object value = stringRedisTemplate.opsForHash().get(KEY_ISV, appId); + if (value == null) { + IsvInfo isvInfo = this.isvInfoMapper.getByAppId(appId); + return this.cache(isvInfo); + } + return JsonUtil.parseObject(String.valueOf(value), IsvDTO.class); + } catch (Exception e) { + log.error("操作redis失败", e); + return super.getIsv(appId); + } } @Override public void reload(String appId) { + IsvInfo isvInfo = isvInfoMapper.getByAppId(appId); + this.cache(isvInfo); + } + @PostConstruct + public void init() { + log.info("load isvInfo to redis"); + List isvInfos = this.isvInfoMapper.listAll(); + for (IsvInfo isvInfo : isvInfos) { + this.cache(isvInfo); + } + } + + protected IsvDTO cache(IsvInfo isvInfo) { + IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new); + stringRedisTemplate.opsForHash().put(KEY_ISV, isvInfo.getAppId(), JsonUtil.toJSONString(isvDTO)); + return isvDTO; } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisSecretManager.java b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisSecretManager.java index 90ecd30b..27829b3f 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisSecretManager.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/manager/impl/RedisSecretManager.java @@ -1,13 +1,59 @@ package com.gitee.sop.index.service.manager.impl; -import com.gitee.sop.index.service.manager.SecretManager; +import com.gitee.sop.index.dao.entity.IsvKeys; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.List; +import java.util.Optional; /** * @author 六如 */ -public class RedisSecretManager implements SecretManager { +@Slf4j +public class RedisSecretManager extends LocalSecretManagerImpl { + + private static final String KEY_ISV = "sop:sec"; + + @Resource + private StringRedisTemplate stringRedisTemplate; + @Override public String getIsvPublicKey(String appId) { - return ""; + try { + Object value = stringRedisTemplate.opsForHash().get(KEY_ISV, appId); + if (value == null) { + return this.reload(appId); + } + return String.valueOf(value); + } catch (Exception e) { + log.error("操作redis失败", e); + return super.getIsvPublicKey(appId); + } } + + @Override + public String reload(String appId) { + IsvKeys isvKeys = this.isvKeysMapper.getByAppId(appId); + return this.cache(appId, isvKeys); + } + + + protected String cache(String appId, IsvKeys isvKeys) { + String publicKey = Optional.ofNullable(isvKeys).map(IsvKeys::getPublicKeyIsv).orElse(""); + stringRedisTemplate.opsForHash().put(KEY_ISV, appId, publicKey); + return publicKey; + } + + @PostConstruct + public void init() { + log.info("load isvKey to redis"); + List isvKeys = this.isvKeysMapper.listAll(); + for (IsvKeys isvKey : isvKeys) { + this.cache(isvKey.getAppId(), isvKey); + } + } + } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java b/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java index b13bff83..ccb31400 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java +++ b/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java @@ -1,15 +1,16 @@ package com.gitee.sop.index.service.validate; import com.gitee.sop.index.common.ApiInfoDTO; -import com.gitee.sop.index.request.ApiRequest; -import com.gitee.sop.index.request.ApiRequestContext; import com.gitee.sop.index.common.ParamNames; import com.gitee.sop.index.common.StatusEnum; import com.gitee.sop.index.config.ApiConfig; import com.gitee.sop.index.exception.ApiException; import com.gitee.sop.index.message.ErrorEnum; +import com.gitee.sop.index.request.ApiRequest; +import com.gitee.sop.index.request.ApiRequestContext; +import com.gitee.sop.index.request.RequestFormatEnum; import com.gitee.sop.index.request.UploadContext; -import com.gitee.sop.index.service.ApiInfoService; +import com.gitee.sop.index.service.manager.ApiManager; import com.gitee.sop.index.service.manager.IpBlacklistManager; import com.gitee.sop.index.service.manager.IsvApiPermissionManager; import com.gitee.sop.index.service.manager.IsvManager; @@ -27,7 +28,6 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; @@ -41,9 +41,7 @@ import java.util.Locale; @Service public class ApiValidator implements Validator { - private static final int MILLISECOND_OF_ONE_SECOND = 1000; - - private static final List FORMAT_LIST = Arrays.asList("json", "xml"); + private static final long MILLISECOND_OF_ONE_SECOND = 1000; private final Signer signer = new AlipaySigner(); @@ -63,7 +61,7 @@ public class ApiValidator implements Validator { private ApiConfig apiConfig; @Resource - private ApiInfoService apiInfoService; + private ApiManager apiCacheManager; @Resource private IpBlacklistManager ipBlacklistManager; @@ -94,7 +92,7 @@ public class ApiValidator implements Validator { checkIP(apiRequestContext); ApiRequest apiRequest = apiRequestContext.getApiRequest(); - ApiInfoDTO apiInfo = apiInfoService.getApi(apiRequest.getMethod(), apiRequest.getVersion()); + ApiInfoDTO apiInfo = apiCacheManager.get(apiRequest.getMethod(), apiRequest.getVersion()); // 检查接口信息 checkApiInfo(apiRequestContext, apiInfo); @@ -271,8 +269,10 @@ public class ApiValidator implements Validator { protected void checkFormat(ApiRequestContext apiRequestContext) { ApiRequest apiRequest = apiRequestContext.getApiRequest(); String format = apiRequest.getFormat(); - boolean contains = FORMAT_LIST.contains(format.toLowerCase()); - if (!contains) { + if (ObjectUtils.isEmpty(format)) { + return; + } + if (RequestFormatEnum.of(format) == RequestFormatEnum.NONE) { throw new ApiException(ErrorEnum.ISV_INVALID_FORMAT, apiRequestContext.getLocale(), apiRequest.takeNameVersion(), format); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/util/JsonUtil.java b/sop-index/src/main/java/com/gitee/sop/index/util/JsonUtil.java new file mode 100644 index 00000000..a8dbcf79 --- /dev/null +++ b/sop-index/src/main/java/com/gitee/sop/index/util/JsonUtil.java @@ -0,0 +1,29 @@ +package com.gitee.sop.index.util; + +import com.alibaba.fastjson2.JSON; +import org.springframework.util.ObjectUtils; + +import java.util.Objects; + +/** + * json工具类,默认用fastjson2实现 + * + * @author 六如 + */ +public class JsonUtil { + + public static String toJSONString(Object object) { + if (object == null) { + return "null"; + } + return JSON.toJSONString(object); + } + + public static T parseObject(String value, Class clazz) { + if (Objects.equals(value, "null") || ObjectUtils.isEmpty(value)) { + return null; + } + return JSON.parseObject(value, clazz); + } + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/util/ResponseUtil.java b/sop-index/src/main/java/com/gitee/sop/index/util/ResponseUtil.java index 96cc7f70..44c6404f 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/util/ResponseUtil.java +++ b/sop-index/src/main/java/com/gitee/sop/index/util/ResponseUtil.java @@ -1,8 +1,10 @@ package com.gitee.sop.index.util; import com.alibaba.fastjson2.JSON; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.gitee.sop.index.request.ApiRequest; import com.gitee.sop.index.request.ApiRequestContext; +import com.gitee.sop.index.request.RequestFormatEnum; import com.gitee.sop.index.response.ApiResponse; import com.gitee.sop.support.request.FileData; import org.apache.commons.io.IOUtils; @@ -16,7 +18,7 @@ import java.io.InputStream; * @author 六如 */ public class ResponseUtil { - + private static final XmlMapper XML_MAPPER = new XmlMapper(); public static void writerFile(FileData fileData, HttpServletResponse response) throws IOException { InputStream inputStream = fileData.getInputStream(); @@ -29,12 +31,20 @@ public class ResponseUtil { IOUtils.copy(inputStream, response.getOutputStream()); } - public static void writerJson(ApiRequestContext apiRequestContext, ApiResponse apiResponse, HttpServletResponse response) throws IOException { + public static void writerText(ApiRequestContext apiRequestContext, ApiResponse apiResponse, HttpServletResponse response) throws IOException { ApiRequest apiRequest = apiRequestContext.getApiRequest(); String charset = apiRequest.getCharset(); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding(charset); - response.getWriter().write(JSON.toJSONString(apiResponse)); + String format = apiRequest.getFormat(); + if (RequestFormatEnum.of(format) == RequestFormatEnum.XML) { + response.setContentType(MediaType.APPLICATION_XML_VALUE); + String xml = XML_MAPPER.writeValueAsString(apiResponse); + response.getWriter().write(xml); + } else { + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + String json = JSON.toJSONString(apiResponse); + response.getWriter().write(json); + } } diff --git a/sop-index/src/main/resources/application-dev.properties b/sop-index/src/main/resources/application-dev.properties index 8f16f232..0b2b9000 100644 --- a/sop-index/src/main/resources/application-dev.properties +++ b/sop-index/src/main/resources/application-dev.properties @@ -1,5 +1,7 @@ dubbo.registry.address=zookeeper://localhost:2181 +mybatis.print-sql=true + # mysql config mysql.host=127.0.0.1:3306 mysql.username=root diff --git a/sop-index/src/main/resources/application-test.properties b/sop-index/src/main/resources/application-test.properties new file mode 100644 index 00000000..1961f052 --- /dev/null +++ b/sop-index/src/main/resources/application-test.properties @@ -0,0 +1,20 @@ +dubbo.registry.address=nacos://localhost:8848 + +mybatis.print-sql=true + +# api manager,local/redis +manager.api=redis +# isv manager,local/redis +manager.isv=redis +# secret manger,local/redis +manager.secret=redis + +# mysql config +mysql.host=127.0.0.1:3306 +mysql.username=root +mysql.password=root + +# redis config +spring.redis.host=localhost +spring.redis.port=6379 +spring.redis.database=0 diff --git a/sop-index/src/main/resources/application.properties b/sop-index/src/main/resources/application.properties index 7b22486b..a3357e91 100644 --- a/sop-index/src/main/resources/application.properties +++ b/sop-index/src/main/resources/application.properties @@ -1,7 +1,18 @@ -spring.profiles.active=dev +spring.profiles.active=test spring.application.name=sop-index server.port=8081 +####### index config ####### +# request entry path +index.path=/api +# api manager,local/redis +manager.api=local +# isv manager,local/redis +manager.isv=local +# secret manger,local/redis +manager.secret=local + + ####### dubbo config ####### dubbo.protocol.name=dubbo dubbo.protocol.port=-1 @@ -40,16 +51,19 @@ spring.datasource.url=jdbc:mysql://${mysql.host}/${mysql.db}?useUnicode=true&cha spring.datasource.username=${mysql.username} spring.datasource.password=${mysql.password} +####### redis config ####### +spring.redis.host=localhost +spring.redis.port=6379 +spring.redis.database=0 + ####### mybatis config ####### mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time # mybatis config file mybatis.config-location=classpath:mybatis/mybatisConfig.xml + # print SQL logging.level.com.gitee.sop.index.dao=error -logging.level.com.gitee.fastmybatis=debug -mybatis.print-sql=true - -# Need not register api -open.register.enable=false +logging.level.com.gitee.fastmybatis=info +mybatis.print-sql=false diff --git a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java index 3f59e4da..b3266c39 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java @@ -68,6 +68,43 @@ public class AlipayClientPostTest extends TestBase { System.out.println(responseData); } + // 输出返回xml格式 + @Test + public void testGetXml() throws Exception { + + // 公共请求参数 + Map params = new HashMap(); + params.put("app_id", appId); + params.put("method", "story.get"); + params.put("format", "xml"); // xml + params.put("charset", "utf-8"); + params.put("sign_type", "RSA2"); + params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + params.put("version", "1.0"); + + // 业务参数 + Map bizContent = new HashMap<>(); + bizContent.put("id", "1"); + bizContent.put("name", "葫芦娃"); + + params.put("biz_content", JSON.toJSONString(bizContent)); + String content = AlipaySignature.getSignContent(params); + String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8"); + params.put("sign", sign); + + System.out.println("----------- 请求信息 -----------"); + System.out.println("请求参数:" + buildParamQuery(params)); + System.out.println("商户秘钥:" + privateKey); + System.out.println("待签名内容:" + content); + System.out.println("签名(sign):" + sign); + System.out.println("URL参数:" + buildUrlQuery(params)); + + System.out.println("----------- 返回结果 -----------"); + String responseData = postJson(url, params);// 发送请求 + // 0success乌鸦喝水1 + System.out.println(responseData); + } + @Test public void testFind() throws Exception { diff --git a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java index ae7e2b96..e1f8ac51 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java @@ -1,12 +1,10 @@ package com.gitee.sop.test; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.Assert; -import org.junit.Test; import java.io.File; import java.io.IOException; @@ -101,7 +99,7 @@ public class AllInOneTest extends TestBase { Assert.assertEquals("isv.route-no-permissions", jsonObject.getString("sub_code")); }); - client.execute(requestBuilder); + //client.execute(requestBuilder); } /**