mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
5.0
This commit is contained in:
167
README.md
167
README.md
@@ -1,144 +1,113 @@
|
||||
# SOP(Simple Open Platform)
|
||||
|
||||
一个开放平台解决方案项目,基于Spring Cloud实现,目标让用户快速搭建自己的开放平台。
|
||||
一个开放平台解决方案项目,基于dubbo实现,目标让用户快速搭建自己的开放平台。
|
||||
|
||||
通过简单的配置后,你的项目就具备了和支付宝开放平台的一样的接口提供能力。
|
||||
|
||||
SOP封装了开放平台大部分功能包括:签名验证、统一异常处理、统一返回内容 、业务参数验证(JSR-303)、秘钥管理等,未来还会实现更多功能。
|
||||
|
||||
## 项目特点
|
||||
|
||||
- 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可。
|
||||
- 架构松耦合,业务代码实现在各自微服务上,SOP不参与业务实现,这也是Spring Cloud微服务体系带来的好处。
|
||||
- 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等。
|
||||
## 项目特点
|
||||
+ 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可。
|
||||
+ 架构松耦合,业务代码实现在各自微服务上,SOP不参与业务实现,这也是dubbo微服务体系带来的好处。
|
||||
+ 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等。
|
||||
|
||||
## 谁可以使用这个项目
|
||||
|
||||
- 有现成的项目,想改造成开放平台供他人调用
|
||||
- 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
|
||||
- 想搭一个开放平台新项目,并结合微服务的方式去维护
|
||||
- 对开放平台感兴趣的朋友
|
||||
+ 有现成的项目,想改造成开放平台供他人调用
|
||||
+ 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
|
||||
+ 想搭一个开放平台新项目,并结合微服务的方式去维护
|
||||
+ 对开放平台感兴趣的朋友
|
||||
|
||||
以上情况都可以考虑使用SOP
|
||||
|
||||
## 例子
|
||||
开放接口定义
|
||||
|
||||
```java
|
||||
// 加一个注解即可
|
||||
@Open("story.get")
|
||||
@RequestMapping("/get")
|
||||
public StoryResult get() {
|
||||
StoryResult result = new StoryResult();
|
||||
result.setId(1L);
|
||||
result.setName("海底小纵队");
|
||||
return result;
|
||||
/**
|
||||
* 支付接口
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Api("支付接口")
|
||||
public interface OpenPayment {
|
||||
|
||||
@ApiOperation(
|
||||
value = "alipay.trade.wap.pay(手机网站支付接口2.0)",
|
||||
notes = "该接口是页面跳转接口,用于生成用户访问支付宝的跳转链接。" +
|
||||
"请在服务端执行支付宝SDK中pageExecute方法,读取响应中的body()结果。" +
|
||||
"该结果用于跳转到支付宝页面,返回到用户浏览器渲染或重定向跳转到支付宝页面。" +
|
||||
"具体使用方法请参考 <a href=\"https://torna.cn\" target=\"_blank\">接入指南</a>"
|
||||
)
|
||||
@Open(value = "alipay.trade.wap.pay", version = "2.0")
|
||||
AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request);
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
接口实现
|
||||
|
||||
```java
|
||||
/**
|
||||
* 开放接口实现
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@DubboService(validation = "true")
|
||||
public class OpenPaymentImpl implements OpenPayment {
|
||||
|
||||
@Override
|
||||
public AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request) {
|
||||
AlipayTradeWapPayResponse alipayTradeWapPayResponse = new AlipayTradeWapPayResponse();
|
||||
alipayTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString());
|
||||
return alipayTradeWapPayResponse;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
调用:
|
||||
|
||||
```java
|
||||
@Test
|
||||
public void testGet() throws Exception {
|
||||
|
||||
// 公共请求参数
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("app_id", appId);
|
||||
params.put("method", "story.get");
|
||||
params.put("method", "alipay.trade.wap.pay");
|
||||
params.put("format", "json");
|
||||
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");
|
||||
params.put("version", "2.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, String> bizContent = new HashMap<>();
|
||||
bizContent.put("id", "1");
|
||||
bizContent.put("name", "葫芦娃");
|
||||
Map<String, Object> bizContent = new HashMap<>();
|
||||
bizContent.put("out_trade_no", "70501111111S001111119");
|
||||
bizContent.put("total_amount", "9.00");
|
||||
bizContent.put("subject", "衣服");
|
||||
bizContent.put("product_code", "QUICK_WAP_WAY");
|
||||
|
||||
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);
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
System.out.println("待签名内容:" + content);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
System.out.println("签名(sign):" + sign);
|
||||
|
||||
params.put("sign", sign);
|
||||
System.out.println("URL参数:" + buildUrlQuery(params));
|
||||
|
||||
System.out.println("----------- 返回结果 -----------");
|
||||
String responseData = get(url, params);// 发送请求
|
||||
String responseData = postJson(url, params);// 发送请求
|
||||
System.out.println(responseData);
|
||||
}
|
||||
```
|
||||
|
||||
## 架构图
|
||||
## 整体架构
|
||||

|
||||
|
||||

|
||||
|
||||
> 如上图所示,整个系统运行后,开发者只需关注微服务中的业务代码,接口变更后重新部署微服务应用即可
|
||||
|
||||
|
||||
## 已完成列表
|
||||
|
||||
- 签名验证
|
||||
- 统一异常处理
|
||||
- 统一返回内容
|
||||
- session管理
|
||||
- 秘钥管理
|
||||
- 微服务端自动验证(JSR-303)
|
||||
- Admin管理平台,统一管理微服务配置,管理路由管理,微服务上下线
|
||||
- 门户网站,提供用户注册账号
|
||||
- 接入方管理+秘钥管理
|
||||
- 接口权限分配
|
||||
- 文件上传/下载
|
||||
- 提供基础SDK(含:Java,C++,C#,Python,Go,Rust,Nodejs)
|
||||
- 接口限流
|
||||
- 文档整合
|
||||
- 应用授权
|
||||
- 监控日志
|
||||
- 注册中心支持nacos/eureka
|
||||
- 网关动态修改参数
|
||||
- 预发布/灰度环境切换
|
||||
|
||||
## 界面预览
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- 门户网站
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 工程说明
|
||||
|
||||
> 运行环境:JDK8,Maven3,[Nacos](https://nacos.io/zh-cn/docs/what-is-nacos.html),Mysql
|
||||
|
||||
- doc:开发文档
|
||||
- sop-common:公共模块,封装常用功能,包含签名校验、错误处理、限流等功能
|
||||
- sop-gateway:网关,统一访问入口,含`Spring Cloud Zuul`和`Spring Cloud Gateway`实现
|
||||
- sop-example:微服务示例,含springboot,springmvc示例
|
||||
- sop-website:开放平台对应网站,提供文档API、沙箱测试等内容
|
||||
- sop-auth:应用授权服务示例
|
||||
- sop-admin:后台管理
|
||||
- sop-sdk:基础sdk,含Java、C#版本
|
||||
- sop-test:接口调用测试用例
|
||||
|
||||
## 分支说明
|
||||
|
||||
- master:发版分支
|
||||
- develop:日常开发分支
|
||||
- eureka:使用eureka注册中心
|
||||
- pr:接受PR的分支,提交PR请提交到此分支
|
||||
|
||||
[更新说明](./changelog.md)
|
||||
|
||||
## 相关文档
|
||||
|
||||
[开发文档](http://durcframework.gitee.io/sop)
|
||||
|
BIN
asset/arc.jpg
Normal file
BIN
asset/arc.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
5
pom.xml
5
pom.xml
@@ -14,18 +14,13 @@
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<description>一个开放平台解决方案项目,基于Spring Cloud实现,目标是能够让用户快速得搭建起自己的开放平台</description>
|
||||
<url></url>
|
||||
|
||||
<modules>
|
||||
<module>doc</module>
|
||||
<!-- <module>sop-common</module>-->
|
||||
<!-- <module>sop-auth</module>-->
|
||||
<module>sop-example</module>
|
||||
<module>sop-admin</module>
|
||||
<!-- <module>sop-gateway</module>-->
|
||||
<module>sop-test</module>
|
||||
<module>sop-sdk</module>
|
||||
<!-- <module>sop-website</module>-->
|
||||
<module>sop-gateway</module>
|
||||
<module>sop-registry</module>
|
||||
<module>sop-support</module>
|
||||
|
155
sop-5.x.sql
155
sop-5.x.sql
@@ -1,155 +0,0 @@
|
||||
CREATE DATABASE IF NOT EXISTS `sop` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
|
||||
USE `sop`;
|
||||
|
||||
DROP TABLE IF EXISTS `api_info`;
|
||||
CREATE TABLE `api_info` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`application` varchar(64) NOT NULL DEFAULT '' COMMENT '应用名称',
|
||||
`api_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口名称',
|
||||
`api_version` varchar(16) NOT NULL DEFAULT '1.0' COMMENT '版本号',
|
||||
`description` varchar(64) DEFAULT '' COMMENT '接口描述',
|
||||
`remark` text COMMENT '备注',
|
||||
`interface_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口class',
|
||||
`method_name` varchar(128) NOT NULL DEFAULT '' COMMENT '方法名称',
|
||||
`param_info` text COMMENT '参数信息',
|
||||
`is_permission` tinyint(4) NOT NULL DEFAULT '0' COMMENT '接口是否需要授权访问',
|
||||
`is_need_Token` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否需要appAuthToken',
|
||||
`reg_source` tinyint(4) NOT NULL DEFAULT '1' COMMENT '注册来源,1-系统注册,2-手动注册',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1启用,0禁用',
|
||||
`add_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_apiname_version` (`api_name`,`api_version`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf32 COMMENT='接口信息表';
|
||||
|
||||
DROP TABLE IF EXISTS `isv_info`;
|
||||
CREATE TABLE `isv_info` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`app_id` varchar(100) NOT NULL COMMENT 'appKey',
|
||||
`status` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '1启用,2禁用',
|
||||
`remark` varchar(512) DEFAULT NULL COMMENT '备注',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_appid` (`app_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf32 COMMENT='isv信息表';
|
||||
|
||||
DROP TABLE IF EXISTS `isv_keys`;
|
||||
CREATE TABLE `isv_keys` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`isv_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'isv_info.id',
|
||||
`key_format` tinyint(4) NOT NULL DEFAULT '1' COMMENT '秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)',
|
||||
`public_key_isv` text NOT NULL COMMENT '开发者生成的公钥',
|
||||
`private_key_isv` text NOT NULL COMMENT '开发者生成的私钥(交给开发者)',
|
||||
`public_key_platform` text NOT NULL COMMENT '平台生成的公钥(交给开发者)',
|
||||
`private_key_platform` text NOT NULL COMMENT '平台生成的私钥',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_appid` (`isv_id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COMMENT='ISV秘钥管理';
|
||||
|
||||
DROP TABLE IF EXISTS `perm_group`;
|
||||
CREATE TABLE `perm_group` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`group_name` varchar(64) NOT NULL COMMENT '分组描述',
|
||||
`is_deleted` tinyint(4) DEFAULT '0' COMMENT '是否删除',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf32 COMMENT='分组表';
|
||||
|
||||
DROP TABLE IF EXISTS `perm_group_permission`;
|
||||
CREATE TABLE `perm_group_permission` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`group_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'perm_group.id',
|
||||
`api_id` varchar(64) NOT NULL COMMENT 'api_info.id',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code_apiid` (`group_id`,`api_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf32 COMMENT='组权限表';
|
||||
|
||||
DROP TABLE IF EXISTS `perm_isv_group`;
|
||||
CREATE TABLE `perm_isv_group` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`isv_id` bigint(20) NOT NULL COMMENT 'isv_info表id',
|
||||
`group_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'perm_group.id',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_role` (`isv_id`,`group_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf32 COMMENT='isv分组';
|
||||
|
||||
DROP TABLE IF EXISTS `sys_admin_user`;
|
||||
CREATE TABLE `sys_admin_user` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`username` varchar(128) NOT NULL DEFAULT '' COMMENT '用户名',
|
||||
`password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
|
||||
`nickname` varchar(64) NOT NULL DEFAULT '' COMMENT '用户名',
|
||||
`email` varchar(128) NOT NULL DEFAULT '' COMMENT '邮箱',
|
||||
`avatar` varchar(128) NOT NULL DEFAULT '' COMMENT '头像',
|
||||
`status` tinyint(4) unsigned NOT NULL DEFAULT '1' COMMENT '状态,1:启用,2:禁用',
|
||||
`reg_type` varchar(32) NOT NULL DEFAULT '1' COMMENT '注册类型,1-系统,2-手动',
|
||||
`add_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_username` (`username`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf32 COMMENT='系统用户表';
|
||||
|
||||
DROP TABLE IF EXISTS `sys_config`;
|
||||
CREATE TABLE `sys_config` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`config_key` varchar(64) NOT NULL DEFAULT '',
|
||||
`config_value` varchar(256) NOT NULL DEFAULT '',
|
||||
`remark` varchar(128) NOT NULL DEFAULT '',
|
||||
`is_deleted` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`add_time` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_configkey` (`config_key`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf32 COMMENT='系统配置表';
|
||||
|
||||
-- insert
|
||||
|
||||
|
||||
INSERT INTO `api_info` (`id`, `application`, `api_name`, `api_version`, `description`, `remark`, `interface_class_name`, `method_name`, `param_info`, `is_permission`, `is_need_Token`, `reg_source`, `status`, `add_time`, `update_time`) VALUES
|
||||
(1, 'story-service', 'story.get', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'getById', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"}]', 0, 0, 1, 1, '2024-09-10 18:34:05', '2024-10-09 09:12:07'),
|
||||
(2, 'story-service', 'story.save', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'save', '[{\"name\":\"storySaveDTO\",\"type\":\"com.gitee.sop.storyweb.open.req.StorySaveDTO\"}]', 0, 0, 1, 1, '2024-09-10 18:34:05', '2024-10-18 20:06:07'),
|
||||
(3, 'story-service', 'story.find', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'getById', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"},{\"name\":\"name\",\"type\":\"java.lang.String\"}]', 0, 0, 1, 1, '2024-09-10 18:38:27', '2024-10-09 09:12:07'),
|
||||
(4, 'story-service', 'story.find2', '1.0', '', '', 'com.gitee.sop.storyweb.open.StoryService', 'getById2', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"},{\"name\":\"name\",\"type\":\"java.lang.String\"}]', 0, 0, 1, 1, '2024-09-10 18:44:51', '2024-09-10 18:44:51'),
|
||||
(5, 'story-service', 'story.find3', '1.0', '', '', 'com.gitee.sop.storyweb.open.StoryService', 'getById2', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"},{\"name\":\"name\",\"type\":\"java.lang.String\"}]', 0, 0, 1, 1, '2024-09-10 18:49:14', '2024-09-10 18:49:14'),
|
||||
(6, 'story-service', 'story.update', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'update', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"},{\"name\":\"storySaveDTO\",\"type\":\"com.gitee.sop.storyweb.open.req.StorySaveDTO\"}]', 0, 0, 1, 1, '2024-09-10 23:00:07', '2024-10-09 09:12:07'),
|
||||
(7, 'story-service', 'story.upload', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'upload', '[{\"name\":\"storySaveDTO\",\"type\":\"com.gitee.sop.storyweb.open.req.StorySaveDTO\"},{\"name\":\"file\",\"type\":\"com.gitee.sop.support.dto.FileData\"}]', 0, 0, 1, 1, '2024-09-13 09:14:03', '2024-10-09 09:12:07'),
|
||||
(8, 'story-service', 'story.upload.more', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'upload2', '[{\"name\":\"storySaveDTO\",\"type\":\"com.gitee.sop.storyweb.open.req.StorySaveDTO\"},{\"name\":\"idCardFront\",\"type\":\"com.gitee.sop.support.dto.FileData\"},{\"name\":\"idCardBack\",\"type\":\"com.gitee.sop.support.dto.FileData\"}]', 0, 0, 1, 1, '2024-09-13 09:22:05', '2024-10-09 09:12:07'),
|
||||
(9, 'story-service', 'story.upload.list', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'upload3', '[{\"name\":\"storySaveDTO\",\"type\":\"com.gitee.sop.storyweb.open.req.StorySaveDTO\"},{\"actualType\":\"com.gitee.sop.support.dto.FileData\",\"name\":\"files\",\"type\":\"java.util.List\"}]', 0, 0, 1, 1, '2024-09-13 09:28:01', '2024-10-09 09:12:07'),
|
||||
(10, 'story-service', 'story.get', '2.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'getByIdV2', '[{\"name\":\"id\",\"type\":\"java.lang.Long\"}]', 0, 0, 1, 1, '2024-09-14 10:40:13', '2024-10-09 09:12:07'),
|
||||
(11, 'story-service', 'story.download', '1.0', '', '', 'com.gitee.sop.storyweb.open.OpenStory', 'download', '[{\"name\":\"id\",\"type\":\"java.lang.Integer\"}]', 0, 0, 2, 1, '2024-09-16 20:56:09', '2024-10-18 20:06:07'),
|
||||
(14, 'q1', 'q11', 'q', 'q1', '备注,内容有点长内容有点长内容有点长内容有点长内容有点长内容有点长', '', '', NULL, 1, 0, 1, 1, '2024-10-06 09:51:47', '2024-10-19 11:47:54'),
|
||||
(15, 'server', 'goods.get', '1.0', '1111', '2222225555', '', '', NULL, 0, 0, 2, 2, '2024-10-10 10:38:59', '2024-10-20 15:51:09');
|
||||
|
||||
INSERT INTO `isv_info` (`id`, `app_id`, `status`, `remark`, `add_time`, `update_time`) VALUES
|
||||
(1, '2019032617262200001', 1, NULL, '2024-09-10 09:23:43', '2024-10-14 11:32:58'),
|
||||
(2, '224', 1, '334', '2024-10-10 10:48:40', '2024-10-10 10:50:39'),
|
||||
(3, '202410111294229455501262848', 1, '杭州限行公司', '2024-10-11 09:17:28', '2024-10-15 09:32:35'),
|
||||
(4, '202410191297295138816524288', 1, 'xx公司', '2024-10-19 20:19:24', '2024-10-21 14:09:42');
|
||||
|
||||
INSERT INTO `isv_keys` (`id`, `isv_id`, `key_format`, `public_key_isv`, `private_key_isv`, `public_key_platform`, `private_key_platform`, `add_time`, `update_time`) VALUES
|
||||
(16, 1, 1, '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', '2024-09-10 09:26:33', '2024-10-19 20:00:37'),
|
||||
(17, 3, 1, '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', '', '', '2024-10-11 09:17:28', '2024-10-11 09:17:28'),
|
||||
(18, 2, 1, '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', '2024-10-19 20:08:11', '2024-10-19 20:08:11'),
|
||||
(19, 4, 1, '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', '2024-10-19 20:23:38', '2024-10-19 20:23:38');
|
||||
|
||||
INSERT INTO `perm_group` (`id`, `group_name`, `is_deleted`, `add_time`, `update_time`) VALUES
|
||||
(1, 'VIP', 0, '2024-10-20 16:23:31', '2024-10-22 09:21:07'),
|
||||
(2, 'VIP2', 1, '2024-10-20 16:25:11', '2024-10-21 14:13:41');
|
||||
|
||||
INSERT INTO `perm_isv_group` (`id`, `isv_id`, `group_id`, `add_time`, `update_time`) VALUES
|
||||
(8, 4, 1, '2024-10-21 14:10:18', '2024-10-21 14:10:18');
|
||||
|
||||
INSERT INTO `sys_admin_user` (`id`, `username`, `password`, `nickname`, `email`, `avatar`, `status`, `reg_type`, `add_time`, `update_time`) VALUES
|
||||
(1, 'admin', '$2a$10$6LWUuQQ8V/rszLo50.qrsuBlNmbYY/q2KSC1BmrxxN5czvOxmF3qK', 'admin', '', '', 1, 'backend', '2024-10-03 08:37:03', '2024-10-03 19:08:48');
|
||||
|
||||
INSERT INTO `sys_config` (`id`, `config_key`, `config_value`, `remark`, `is_deleted`, `add_time`, `update_time`) VALUES
|
||||
(1, 'admin.jwt.secret', 'UXJC8R3NmAvj9kFKWwBgYu6y3naXh7', '', 0, '2024-10-02 21:20:41', '2024-10-02 21:20:41'),
|
||||
(2, 'admin.password-salt', 'Khq9RnXZCGsWz', '', 0, '2024-10-02 21:20:41', '2024-10-02 21:20:41');
|
25
sop-admin/sop-admin-server/.gitignore
vendored
25
sop-admin/sop-admin-server/.gitignore
vendored
@@ -1,25 +0,0 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
/local-config/
|
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-parent</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>sop-admin-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- easyopen starter -->
|
||||
<dependency>
|
||||
<groupId>net.oschina.durcframework</groupId>
|
||||
<artifactId>easyopen-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.oschina.durcframework</groupId>
|
||||
<artifactId>fastmybatis-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- optional-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<!-- 打包时跳过测试 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>maven2</id>
|
||||
<name>maven2</name>
|
||||
<url>https://repo1.maven.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
@@ -1,22 +0,0 @@
|
||||
# sop admin服务端
|
||||
|
||||
# 使用步骤
|
||||
|
||||
- 打开`application-dev.yml`,修改数据库`username/password`,指定nacos地址
|
||||
- 运行`SopAdminServerApplication.java`
|
||||
- 访问:`http://localhost:8082`
|
||||
|
||||
登录账号:admin/123456
|
||||
|
||||
后台用户表:admin_user_info
|
||||
|
||||
- 密码保存规则:`md5(username + md5(password) + username)`
|
||||
|
||||
```text
|
||||
username: admin
|
||||
password: 123456
|
||||
即
|
||||
md5("admin" + md5(123456) + "admin")
|
||||
```
|
||||
|
||||
详见:com.gitee.sop.adminserver.AccountTest
|
@@ -1,12 +0,0 @@
|
||||
package com.gitee.sop.adminserver;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SopAdminServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SopAdminServerApplication.class, args);
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class IdParam {
|
||||
@NotNull(message = "id不能为空")
|
||||
@ApiDocField(description = "id")
|
||||
private Long id;
|
||||
}
|
@@ -1,51 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.demo;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.sop.adminserver.api.demo.param.GoodsParam;
|
||||
import com.gitee.sop.adminserver.api.demo.result.Goods;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 业务类
|
||||
*
|
||||
* @author 六如
|
||||
*
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("商品模块")
|
||||
public class GoodsApi {
|
||||
|
||||
@Api(name = "goods.get")
|
||||
@ApiDocMethod(description = "获取商品")
|
||||
public Goods getGoods(GoodsParam param) {
|
||||
Goods goods = new Goods();
|
||||
goods.setId(1L);
|
||||
goods.setGoods_name("苹果iPhoneX");
|
||||
goods.setPrice(new BigDecimal(8000));
|
||||
return goods;
|
||||
}
|
||||
|
||||
@Api(name = "goods.list", version = "2.0")
|
||||
@ApiDocMethod(description = "获取商品列表", results = {
|
||||
@ApiDocField(description = "商品列表", name = "list", elementClass = Goods.class) })
|
||||
public List<Goods> listGoods(GoodsParam param) {
|
||||
Goods goods = new Goods();
|
||||
goods.setId(1L);
|
||||
goods.setGoods_name("iPhoneX");
|
||||
goods.setPrice(new BigDecimal(8000));
|
||||
|
||||
Goods goods2 = new Goods();
|
||||
goods2.setId(2L);
|
||||
goods2.setGoods_name("三星");
|
||||
goods2.setPrice(new BigDecimal(7000));
|
||||
return Arrays.asList(goods, goods2);
|
||||
}
|
||||
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.demo.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
public class GoodsParam {
|
||||
|
||||
@ApiDocField(description = "商品名称", required = true, example = "iphoneX")
|
||||
@NotEmpty(message = "商品名称不能为空")
|
||||
@Length(min = 3, max = 20, message = "{goods.name.length}=3,20")
|
||||
private String goods_name;
|
||||
|
||||
public String getGoods_name() {
|
||||
return goods_name;
|
||||
}
|
||||
|
||||
public void setGoods_name(String goods_name) {
|
||||
this.goods_name = goods_name;
|
||||
}
|
||||
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.demo.result;
|
||||
|
||||
import com.gitee.easyopen.doc.DataType;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@XStreamAlias("goods")
|
||||
public class Goods {
|
||||
|
||||
@ApiDocField(description = "id")
|
||||
private Long id;
|
||||
@ApiDocField(description = "商品名称")
|
||||
private String goods_name;
|
||||
@ApiDocField(description = "价格", dataType = DataType.FLOAT)
|
||||
private BigDecimal price;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getGoods_name() {
|
||||
return goods_name;
|
||||
}
|
||||
|
||||
public void setGoods_name(String goods_name) {
|
||||
this.goods_name = goods_name;
|
||||
}
|
||||
|
||||
public BigDecimal getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(BigDecimal price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Goods [id=" + id + ", goods_name=" + goods_name + ", price=" + price + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -1,298 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.DataType;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.IdParam;
|
||||
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormAdd;
|
||||
import com.gitee.sop.adminserver.api.isv.param.IsvInfoFormUpdate;
|
||||
import com.gitee.sop.adminserver.api.isv.param.IsvKeysFormUpdate;
|
||||
import com.gitee.sop.adminserver.api.isv.param.IsvKeysGen;
|
||||
import com.gitee.sop.adminserver.api.isv.param.IsvPageParam;
|
||||
import com.gitee.sop.adminserver.api.isv.result.IsvDetailDTO;
|
||||
import com.gitee.sop.adminserver.api.isv.result.IsvInfoVO;
|
||||
import com.gitee.sop.adminserver.api.isv.result.IsvKeysGenVO;
|
||||
import com.gitee.sop.adminserver.api.isv.result.IsvKeysVO;
|
||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
||||
import com.gitee.sop.adminserver.bean.NacosConfigs;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.ChannelOperation;
|
||||
import com.gitee.sop.adminserver.common.IdGen;
|
||||
import com.gitee.sop.adminserver.common.RSATool;
|
||||
import com.gitee.sop.adminserver.entity.IsvInfo;
|
||||
import com.gitee.sop.adminserver.entity.IsvKeys;
|
||||
import com.gitee.sop.adminserver.entity.PermIsvRole;
|
||||
import com.gitee.sop.adminserver.entity.PermRole;
|
||||
import com.gitee.sop.adminserver.mapper.IsvInfoMapper;
|
||||
import com.gitee.sop.adminserver.mapper.IsvKeysMapper;
|
||||
import com.gitee.sop.adminserver.mapper.PermIsvRoleMapper;
|
||||
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
|
||||
import com.gitee.sop.adminserver.service.ConfigPushService;
|
||||
import com.gitee.sop.adminserver.service.RoutePermissionService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("ISV管理")
|
||||
@Slf4j
|
||||
public class IsvApi {
|
||||
|
||||
public static final byte SIGN_TYPE_RSA = 1;
|
||||
public static final byte SIGN_TYPE_MD5 = 2;
|
||||
|
||||
static Map<String, Byte> SIGN_TYPE_MAP = new HashMap<>();
|
||||
static {
|
||||
SIGN_TYPE_MAP.put("rsa", (byte) SIGN_TYPE_RSA);
|
||||
SIGN_TYPE_MAP.put("md5", (byte) SIGN_TYPE_MD5);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
IsvInfoMapper isvInfoMapper;
|
||||
|
||||
@Autowired
|
||||
IsvKeysMapper isvKeysMapper;
|
||||
|
||||
@Autowired
|
||||
PermIsvRoleMapper permIsvRoleMapper;
|
||||
|
||||
@Autowired
|
||||
PermRoleMapper permRoleMapper;
|
||||
|
||||
@Autowired
|
||||
RoutePermissionService routePermissionService;
|
||||
|
||||
@Autowired
|
||||
private ConfigPushService configPushService;
|
||||
|
||||
@Value("${sop.sign-type}")
|
||||
private String sopSignType;
|
||||
|
||||
@Api(name = "isv.info.page")
|
||||
@ApiDocMethod(description = "isv列表", results = {
|
||||
@ApiDocField(name = "pageIndex", description = "第几页", dataType = DataType.INT, example = "1"),
|
||||
@ApiDocField(name = "pageSize", description = "每页几条数据", dataType = DataType.INT, example = "10"),
|
||||
@ApiDocField(name = "total", description = "每页几条数据", dataType = DataType.LONG, example = "100"),
|
||||
@ApiDocField(name = "rows", description = "数据", dataType = DataType.ARRAY, elementClass = IsvInfoVO.class)
|
||||
})
|
||||
PageInfo<IsvInfoVO> pageIsv(IsvPageParam param) {
|
||||
Query query = Query.build(param);
|
||||
query.orderby("id", Sort.DESC);
|
||||
PageInfo<IsvInfo> pageInfo = MapperUtil.query(isvInfoMapper, query);
|
||||
List<IsvInfo> list = pageInfo.getList();
|
||||
|
||||
List<IsvInfoVO> retList = list.stream()
|
||||
.map(isvInfo -> {
|
||||
return buildIsvVO(isvInfo);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
PageInfo<IsvInfoVO> pageInfoRet = new PageInfo<>();
|
||||
pageInfoRet.setTotal(pageInfo.getTotal());
|
||||
pageInfoRet.setList(retList);
|
||||
|
||||
return pageInfoRet;
|
||||
}
|
||||
|
||||
@Api(name = "isv.info.get")
|
||||
@ApiDocMethod(description = "获取isv")
|
||||
IsvInfoVO getIsvVO(IdParam param) {
|
||||
IsvInfo isvInfo = isvInfoMapper.getById(param.getId());
|
||||
return buildIsvVO(isvInfo);
|
||||
}
|
||||
|
||||
@Api(name = "isv.keys.get")
|
||||
@ApiDocMethod(description = "获取isv2")
|
||||
IsvKeysVO getIsvKeys(@NotBlank(message = "appKey不能为空")
|
||||
@ApiDocField(description = "appKey")
|
||||
String appKey) {
|
||||
IsvKeys isvKeys = isvKeysMapper.getByColumn("app_key", appKey);
|
||||
IsvKeysVO isvDetailVO = new IsvKeysVO();
|
||||
if (isvKeys != null) {
|
||||
CopyUtil.copyProperties(isvKeys, isvDetailVO);
|
||||
}
|
||||
isvDetailVO.setAppKey(appKey);
|
||||
isvDetailVO.setSignType(getSignType());
|
||||
return isvDetailVO;
|
||||
}
|
||||
|
||||
private IsvInfoVO buildIsvVO(IsvInfo isvInfo) {
|
||||
if (isvInfo == null) {
|
||||
return null;
|
||||
}
|
||||
IsvInfoVO vo = new IsvInfoVO();
|
||||
CopyUtil.copyProperties(isvInfo, vo);
|
||||
vo.setRoleList(this.buildIsvRole(isvInfo));
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建ISV拥有的角色
|
||||
*
|
||||
* @param permClient
|
||||
* @return
|
||||
*/
|
||||
List<RoleVO> buildIsvRole(IsvInfo permClient) {
|
||||
List<String> roleCodeList = routePermissionService.listClientRoleCode(permClient.getId());
|
||||
if (CollectionUtils.isEmpty(roleCodeList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<PermRole> list = permRoleMapper.list(new Query().in("role_code", roleCodeList));
|
||||
|
||||
return list.stream()
|
||||
.map(permRole -> {
|
||||
RoleVO vo = new RoleVO();
|
||||
CopyUtil.copyProperties(permRole, vo);
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Api(name = "isv.info.add")
|
||||
@ApiDocMethod(description = "添加isv")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void addIsv(IsvInfoFormAdd param) throws Exception {
|
||||
String appKey = new SimpleDateFormat("yyyyMMdd").format(new Date()) + IdGen.nextId();
|
||||
IsvInfo rec = new IsvInfo();
|
||||
rec.setAppKey(appKey);
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
||||
isvInfoMapper.saveIgnoreNull(rec);
|
||||
if (CollectionUtils.isNotEmpty(param.getRoleCode())) {
|
||||
this.saveIsvRole(rec, param.getRoleCode());
|
||||
}
|
||||
IsvKeysGenVO isvKeysGenVO = this.createIsvKeys();
|
||||
IsvKeys isvKeys = new IsvKeys();
|
||||
isvKeys.setAppKey(appKey);
|
||||
isvKeys.setSignType(getSignType());
|
||||
CopyUtil.copyPropertiesIgnoreNull(isvKeysGenVO, isvKeys);
|
||||
isvKeysMapper.saveIgnoreNull(isvKeys);
|
||||
|
||||
this.sendChannelMsg(rec.getAppKey());
|
||||
}
|
||||
|
||||
private byte getSignType() {
|
||||
return SIGN_TYPE_MAP.getOrDefault(sopSignType, SIGN_TYPE_RSA);
|
||||
}
|
||||
|
||||
@Api(name = "isv.info.update")
|
||||
@ApiDocMethod(description = "修改isv")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateIsv(IsvInfoFormUpdate param) {
|
||||
IsvInfo rec = isvInfoMapper.getById(param.getId());
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, rec);
|
||||
isvInfoMapper.updateIgnoreNull(rec);
|
||||
this.saveIsvRole(rec, param.getRoleCode());
|
||||
|
||||
this.sendChannelMsg(rec.getAppKey());
|
||||
}
|
||||
|
||||
@Api(name = "isv.keys.update")
|
||||
@ApiDocMethod(description = "修改isv")
|
||||
public void updateIsvKeys(IsvKeysFormUpdate param) {
|
||||
IsvKeys isvKeys = isvKeysMapper.getByColumn("app_key", param.getAppKey());
|
||||
if (isvKeys == null) {
|
||||
isvKeys = new IsvKeys();
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, isvKeys);
|
||||
isvKeys.setSignType(getSignType());
|
||||
isvKeysMapper.saveIgnoreNull(isvKeys);
|
||||
} else {
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, isvKeys);
|
||||
isvKeysMapper.updateIgnoreNull(isvKeys);
|
||||
}
|
||||
|
||||
this.sendChannelMsg(isvKeys.getAppKey());
|
||||
}
|
||||
|
||||
private void sendChannelMsg(String appKey) {
|
||||
IsvDetailDTO isvDetail = isvInfoMapper.getIsvDetail(appKey);
|
||||
if (isvDetail == null) {
|
||||
return;
|
||||
}
|
||||
ChannelMsg channelMsg = new ChannelMsg(ChannelOperation.ISV_INFO_UPDATE, isvDetail);
|
||||
configPushService.publishConfig(NacosConfigs.DATA_ID_ISV, NacosConfigs.GROUP_CHANNEL, channelMsg);
|
||||
}
|
||||
|
||||
private IsvKeysGenVO createIsvKeys() throws Exception {
|
||||
IsvKeysGenVO isvFormVO = new IsvKeysGenVO();
|
||||
String secret = IdGen.uuid();
|
||||
|
||||
isvFormVO.setSecret(secret);
|
||||
|
||||
RSATool rsaToolIsv = new RSATool(RSATool.KeyFormat.PKCS8, RSATool.KeyLength.LENGTH_2048);
|
||||
RSATool.KeyStore keyStoreIsv = rsaToolIsv.createKeys();
|
||||
isvFormVO.setPublicKeyIsv(keyStoreIsv.getPublicKey());
|
||||
isvFormVO.setPrivateKeyIsv(keyStoreIsv.getPrivateKey());
|
||||
|
||||
isvFormVO.setPublicKeyPlatform("");
|
||||
isvFormVO.setPrivateKeyPlatform("");
|
||||
return isvFormVO;
|
||||
}
|
||||
|
||||
@Api(name = "isv.keys.gen")
|
||||
@ApiDocMethod(description = "生成公私钥")
|
||||
RSATool.KeyStore createPubPriKey(IsvKeysGen param) throws Exception {
|
||||
RSATool.KeyFormat format = RSATool.KeyFormat.PKCS8;
|
||||
Byte keyFormat = param.getKeyFormat();
|
||||
if (keyFormat != null && keyFormat == 2) {
|
||||
format = RSATool.KeyFormat.PKCS1;
|
||||
}
|
||||
RSATool rsaTool = new RSATool(format, RSATool.KeyLength.LENGTH_2048);
|
||||
return rsaTool.createKeys();
|
||||
}
|
||||
|
||||
@Api(name = "isv.secret.gen")
|
||||
@ApiDocMethod(description = "生成MD秘钥")
|
||||
String createSecret() throws Exception {
|
||||
return IdGen.uuid();
|
||||
}
|
||||
|
||||
void saveIsvRole(IsvInfo isvInfo, List<String> roleCodeList) {
|
||||
Query query = new Query();
|
||||
Long isvId = isvInfo.getId();
|
||||
query.eq("isv_id", isvId);
|
||||
permIsvRoleMapper.deleteByQuery(query);
|
||||
|
||||
List<PermIsvRole> tobeSaveList = roleCodeList.stream()
|
||||
.map(roleCode -> {
|
||||
PermIsvRole rec = new PermIsvRole();
|
||||
rec.setIsvId(isvId);
|
||||
rec.setRoleCode(roleCode);
|
||||
return rec;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isNotEmpty(tobeSaveList)) {
|
||||
permIsvRoleMapper.saveBatch(tobeSaveList);
|
||||
}
|
||||
|
||||
try {
|
||||
routePermissionService.sendIsvRolePermissionMsg(isvInfo.getAppKey(), roleCodeList);
|
||||
} catch (Exception e) {
|
||||
log.error("同步角色失败,isvInfo:{}, roleCodeList:{}", isvInfo, roleCodeList);
|
||||
throw new BizException("同步角色失败,请查看网关日志");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.support.PageEasyui;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.isv.param.RoleForm;
|
||||
import com.gitee.sop.adminserver.api.isv.param.RolePageParam;
|
||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.entity.PermRole;
|
||||
import com.gitee.sop.adminserver.entity.PermRolePermission;
|
||||
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
|
||||
import com.gitee.sop.adminserver.mapper.PermRolePermissionMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("ISV管理")
|
||||
@Slf4j
|
||||
public class RoleApi {
|
||||
|
||||
@Autowired
|
||||
PermRoleMapper permRoleMapper;
|
||||
|
||||
@Autowired
|
||||
PermRolePermissionMapper permRolePermissionMapper;
|
||||
|
||||
@Api(name = "role.listall")
|
||||
List<RoleVO> roleListall() {
|
||||
Query query = new Query();
|
||||
query.orderby("id", Sort.ASC);
|
||||
return permRoleMapper.list(query).stream()
|
||||
.map(permRole -> {
|
||||
RoleVO vo = new RoleVO();
|
||||
CopyUtil.copyProperties(permRole, vo);
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ApiDocMethod(description = "获取角色,分页")
|
||||
@Api(name = "role.page")
|
||||
PageEasyui<RoleVO> pageRole(RolePageParam rolePage) {
|
||||
Query query = Query.build(rolePage);
|
||||
return MapperUtil.queryForEasyuiDatagrid(permRoleMapper, query, RoleVO.class);
|
||||
}
|
||||
|
||||
@Api(name = "role.add")
|
||||
void addRole(RoleForm roleForm) {
|
||||
PermRole rec = permRoleMapper.getByColumn("role_code", roleForm.getRoleCode());
|
||||
if (rec != null) {
|
||||
throw new BizException("角色码已存在");
|
||||
}
|
||||
PermRole permRole = new PermRole();
|
||||
CopyUtil.copyPropertiesIgnoreNull(roleForm, permRole);
|
||||
permRoleMapper.saveIgnoreNull(permRole);
|
||||
}
|
||||
|
||||
@Api(name = "role.update")
|
||||
void updateRole(RoleForm roleForm) {
|
||||
PermRole rec = permRoleMapper.getById(roleForm.getId());
|
||||
rec.setDescription(roleForm.getDescription());
|
||||
permRoleMapper.updateIgnoreNull(rec);
|
||||
}
|
||||
|
||||
@Api(name = "role.del")
|
||||
void delRole(long id) {
|
||||
PermRole rec = permRoleMapper.getById(id);
|
||||
PermRolePermission rolePermission = permRolePermissionMapper.getByColumn("role_code", rec.getRoleCode());
|
||||
if (rolePermission != null) {
|
||||
throw new BizException("该角色已使用,无法删除");
|
||||
}
|
||||
permRoleMapper.deleteById(id);
|
||||
}
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvInfoForm {
|
||||
|
||||
/** 0启用,1禁用, 数据库字段:status */
|
||||
@ApiDocField(description = "状态:0:启用,1:禁用")
|
||||
private Byte status = 0;
|
||||
|
||||
@ApiDocField(description = "备注")
|
||||
@Length(max = 100, message = "长度不得唱过100")
|
||||
private String remark;
|
||||
|
||||
@ApiDocField(description = "roleCode数组", elementClass = String.class)
|
||||
private List<String> roleCode = Collections.emptyList();
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class IsvInfoFormAdd extends IsvInfoForm {
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class IsvInfoFormUpdate extends IsvInfoForm {
|
||||
@ApiDocField(description = "id")
|
||||
@NotNull(message = "id不能为空")
|
||||
private Long id;
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysFormUpdate {
|
||||
/** appKey, 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey", example = "aaaa")
|
||||
@NotBlank(message = "appKey不能为空")
|
||||
@Length(max = 100,message = "appKey长度不能超过100")
|
||||
private String appKey;
|
||||
|
||||
/** secret, 数据库字段:secret */
|
||||
@ApiDocField(description = "secret", example = "bbbb")
|
||||
private String secret;
|
||||
|
||||
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */
|
||||
@ApiDocField(description = "秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)", example = "1")
|
||||
@Min(value = 1, message = "秘钥格式错误")
|
||||
@Max(value = 2, message = "秘钥格式错误")
|
||||
private Byte keyFormat;
|
||||
|
||||
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||
@ApiDocField(description = "平台生成的公钥")
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||
@ApiDocField(description = "平台生成的私钥")
|
||||
private String privateKeyPlatform;
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysGen {
|
||||
@ApiDocField(description = "秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用)", example = "1")
|
||||
@Min(value = 1, message = "秘钥格式错误")
|
||||
@Max(value = 2, message = "秘钥格式错误")
|
||||
private Byte keyFormat;
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.DataType;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocBean;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ApiDocBean(fields = {
|
||||
@ApiDocField(name = "pageIndex", description = "第几页", dataType = DataType.INT, example = "1"),
|
||||
@ApiDocField(name = "pageSize", description = "每页几条数据", dataType = DataType.INT, example = "10"),
|
||||
})
|
||||
public class IsvPageParam extends PageParam {
|
||||
@ApiDocField(name = "appKey", description = "appKey", dataType = DataType.STRING, example = "111111")
|
||||
@Condition(ignoreEmptyString = true)
|
||||
private String appKey;
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RoleForm {
|
||||
@ApiDocField(description = "id")
|
||||
private Long id;
|
||||
|
||||
@ApiDocField(description = "角色码")
|
||||
@NotBlank(message = "roleCode不能为空")
|
||||
@Length(max = 64)
|
||||
private String roleCode;
|
||||
|
||||
@ApiDocField(description = "描述")
|
||||
private String description;
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RolePageParam extends PageParam {
|
||||
@ApiDocField(description = "角色码")
|
||||
@Condition(operator = Operator.like)
|
||||
private String roleCode;
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvAppKeyGenVO {
|
||||
private String appKey;
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvDetailDTO {
|
||||
|
||||
/** appKey, 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey", example = "aaaa")
|
||||
private String appKey;
|
||||
|
||||
/** 0启用,1禁用, 数据库字段:status */
|
||||
@ApiDocField(description = "状态:0启用,1禁用")
|
||||
private Byte status;
|
||||
|
||||
/** secret, 数据库字段:secret */
|
||||
@ApiDocField(description = "secret", example = "bbbb")
|
||||
private String secret;
|
||||
|
||||
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||
@ApiDocField(description = "开发者生成的公钥")
|
||||
private String publicKeyIsv;
|
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||
@ApiDocField(description = "平台生成的私钥")
|
||||
private String privateKeyPlatform;
|
||||
|
||||
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||
private Byte signType;
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvInfoVO {
|
||||
/** 数据库字段:id */
|
||||
@ApiDocField(description = "id", example = "1")
|
||||
private Long id;
|
||||
|
||||
/** appKey, 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey", example = "aaaa")
|
||||
private String appKey;
|
||||
|
||||
/** 0启用,1禁用, 数据库字段:status */
|
||||
@ApiDocField(description = "状态:0启用,1禁用")
|
||||
private Byte status;
|
||||
|
||||
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||
private Byte signType;
|
||||
|
||||
@ApiDocField(description = "备注")
|
||||
private String remark;
|
||||
|
||||
private Long userId;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
@ApiDocField(description = "添加时间")
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
@ApiDocField(description = "修改时间")
|
||||
private Date gmtModified;
|
||||
|
||||
@ApiDocField(description = "角色列表")
|
||||
private List<RoleVO> roleList;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysGenVO {
|
||||
/** secret, 数据库字段:secret */
|
||||
private String secret;
|
||||
|
||||
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||
private String publicKeyIsv;
|
||||
|
||||
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||
private String privateKeyIsv;
|
||||
|
||||
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||
private String privateKeyPlatform;
|
||||
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvKeysVO {
|
||||
|
||||
/** appKey, 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey", example = "aaaa")
|
||||
private String appKey;
|
||||
|
||||
/** secret, 数据库字段:secret */
|
||||
@ApiDocField(description = "secret", example = "bbbb")
|
||||
private String secret;
|
||||
|
||||
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */
|
||||
private Byte keyFormat = 1;
|
||||
|
||||
/** 开发者生成的公钥, 数据库字段:public_key_isv */
|
||||
private String publicKeyIsv;
|
||||
|
||||
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */
|
||||
private String privateKeyIsv;
|
||||
|
||||
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */
|
||||
private String publicKeyPlatform;
|
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */
|
||||
private String privateKeyPlatform;
|
||||
|
||||
@ApiDocField(description = "签名类型:1:RSA2,2:MD5")
|
||||
private Byte signType = 1;
|
||||
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.isv.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RoleVO {
|
||||
@ApiDocField(description = "id")
|
||||
private Long id;
|
||||
|
||||
@ApiDocField(description = "角色码")
|
||||
private String roleCode;
|
||||
|
||||
@ApiDocField(description = "描述")
|
||||
private String description;
|
||||
|
||||
@ApiDocField(description = "创建时间")
|
||||
private Date gmtCreate;
|
||||
|
||||
@ApiDocField(description = "修改时间")
|
||||
private Date gmtModified;
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.support.PageEasyui;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.service.param.ConfigIpBlackForm;
|
||||
import com.gitee.sop.adminserver.api.service.param.ConfigIpBlacklistPageParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.ConfigIpBlacklistVO;
|
||||
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
||||
import com.gitee.sop.adminserver.bean.NacosConfigs;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.ChannelOperation;
|
||||
import com.gitee.sop.adminserver.entity.ConfigIpBlacklist;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigIpBlacklistMapper;
|
||||
import com.gitee.sop.adminserver.service.ConfigPushService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("IP黑名单管理")
|
||||
@Slf4j
|
||||
public class IPBlacklistApi {
|
||||
|
||||
@Autowired
|
||||
ConfigIpBlacklistMapper configIpBlacklistMapper;
|
||||
|
||||
@Autowired
|
||||
private ConfigPushService configPushService;
|
||||
|
||||
@ApiDocMethod(description = "获取IP黑名单,分页")
|
||||
@Api(name = "ip.blacklist.page")
|
||||
PageEasyui<ConfigIpBlacklistVO> page(ConfigIpBlacklistPageParam form) {
|
||||
Query query = Query.build(form);
|
||||
query.orderby("id", Sort.DESC);
|
||||
return MapperUtil.queryForEasyuiDatagrid(configIpBlacklistMapper, query, ConfigIpBlacklistVO.class);
|
||||
}
|
||||
|
||||
@ApiDocMethod(description = "IP黑名单--新增")
|
||||
@Api(name = "ip.blacklist.add")
|
||||
void add(ConfigIpBlackForm form) {
|
||||
ConfigIpBlacklist rec = configIpBlacklistMapper.getByColumn("ip", form.getIp());
|
||||
if (rec != null) {
|
||||
throw new BizException("IP已添加");
|
||||
}
|
||||
rec = new ConfigIpBlacklist();
|
||||
CopyUtil.copyPropertiesIgnoreNull(form, rec);
|
||||
configIpBlacklistMapper.saveIgnoreNull(rec);
|
||||
try {
|
||||
this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_ADD);
|
||||
} catch (Exception e) {
|
||||
log.error("推送IP黑名单失败, rec:{}",rec, e);
|
||||
throw new BizException("推送IP黑名单失败");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiDocMethod(description = "IP黑名单--修改")
|
||||
@Api(name = "ip.blacklist.update")
|
||||
void update(ConfigIpBlackForm form) {
|
||||
ConfigIpBlacklist rec = configIpBlacklistMapper.getById(form.getId());
|
||||
CopyUtil.copyPropertiesIgnoreNull(form, rec);
|
||||
configIpBlacklistMapper.updateIgnoreNull(rec);
|
||||
}
|
||||
|
||||
@ApiDocMethod(description = "IP黑名单--删除")
|
||||
@Api(name = "ip.blacklist.del")
|
||||
void del(long id) {
|
||||
ConfigIpBlacklist rec = configIpBlacklistMapper.getById(id);
|
||||
if (rec == null) {
|
||||
return;
|
||||
}
|
||||
configIpBlacklistMapper.deleteById(id);
|
||||
try {
|
||||
this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_DELETE);
|
||||
} catch (Exception e) {
|
||||
log.error("推送IP黑名单失败, rec:{}",rec, e);
|
||||
throw new BizException("推送IP黑名单失败");
|
||||
}
|
||||
}
|
||||
|
||||
public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, ChannelOperation channelOperation) {
|
||||
ChannelMsg channelMsg = new ChannelMsg(channelOperation, configIpBlacklist);
|
||||
configPushService.publishConfig(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, channelMsg);
|
||||
}
|
||||
|
||||
}
|
@@ -1,95 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.fastmybatis.core.PageInfo;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.service.param.LimitNewAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.LimitNewParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.LimitNewUpdateParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.LimitNewVO;
|
||||
import com.gitee.sop.adminserver.bean.ConfigLimitDto;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.entity.ConfigLimit;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigLimitMapper;
|
||||
import com.gitee.sop.adminserver.service.RouteConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("服务管理-限流管理")
|
||||
@Slf4j
|
||||
public class LimitNewApi {
|
||||
|
||||
@Autowired
|
||||
RouteConfigService routeConfigService;
|
||||
|
||||
@Autowired
|
||||
ConfigLimitMapper configLimitMapper;
|
||||
|
||||
@Api(name = "config.limit.list")
|
||||
@ApiDocMethod(description = "限流列表(新)", elementClass = LimitNewVO.class)
|
||||
PageInfo<ConfigLimit> listLimit(LimitNewParam param) {
|
||||
Query query = Query.build(param);
|
||||
query.orderby("route_id", Sort.ASC)
|
||||
.orderby("app_key", Sort.ASC)
|
||||
.orderby("order_index", Sort.ASC);
|
||||
PageInfo<ConfigLimit> pageInfo = MapperUtil.query(configLimitMapper, query);
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
@Api(name = "config.limit.add")
|
||||
@ApiDocMethod(description = "新增限流(新)")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createLimtit(LimitNewAddParam param) {
|
||||
ConfigLimit configLimit = new ConfigLimit();
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
|
||||
configLimitMapper.save(configLimit);
|
||||
ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit);
|
||||
try {
|
||||
routeConfigService.sendLimitConfigMsg(configLimitDto);
|
||||
} catch (Exception e) {
|
||||
log.error("推送限流消息错误, param:{}", param, e);
|
||||
throw new BizException("新增失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "config.limit.update")
|
||||
@ApiDocMethod(description = "修改限流(新)")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateLimtit(LimitNewUpdateParam param) {
|
||||
ConfigLimit configLimit = configLimitMapper.getById(param.getId());
|
||||
if (configLimit == null) {
|
||||
configLimit = new ConfigLimit();
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
|
||||
configLimitMapper.save(configLimit);
|
||||
} else {
|
||||
CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
|
||||
configLimitMapper.update(configLimit);
|
||||
}
|
||||
ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit);
|
||||
try {
|
||||
routeConfigService.sendLimitConfigMsg(configLimitDto);
|
||||
} catch (Exception e) {
|
||||
log.error("推送限流消息错误, param:{}", param, e);
|
||||
throw new BizException("修改失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigLimitDto buildConfigLimitDto(ConfigLimit configLimit) {
|
||||
ConfigLimitDto configLimitDto = new ConfigLimitDto();
|
||||
CopyUtil.copyPropertiesIgnoreNull(configLimit, configLimitDto);
|
||||
return configLimitDto;
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.verify.DefaultMd5Verifier;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.adminserver.api.service.param.LogMonitorInstanceAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.LogMonitorInstanceVO;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.QueryUtil;
|
||||
import com.gitee.sop.adminserver.entity.ConfigCommon;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigCommonMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("服务管理-日志监控")
|
||||
@Slf4j
|
||||
public class LogApi {
|
||||
|
||||
public static final String LOG_MONITOR_INSTANCE = "log.monitor.instance";
|
||||
public static final String CODE_SUCCESS = "10000";
|
||||
private static final String CODE_KEY = "code";
|
||||
public static final String SOP_LIST_ERRORS_PATH = "/sop/listErrors";
|
||||
public static final String SOP_CLEAR_ERRORS_PATH = "/sop/clearErrors";
|
||||
|
||||
@Autowired
|
||||
ConfigCommonMapper configCommonMapper;
|
||||
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Value("${sop.secret}")
|
||||
private String secret;
|
||||
|
||||
@Api(name = "monitor.log.list")
|
||||
@ApiDocMethod(description = "获取监控日志")
|
||||
List<LogMonitorInstanceVO> listLog() {
|
||||
List<ConfigCommon> configCommonList = configCommonMapper.listByColumn("config_group", LOG_MONITOR_INSTANCE);
|
||||
List<LogMonitorInstanceVO> ret = new ArrayList<>();
|
||||
int id = 1;
|
||||
for (ConfigCommon configCommon : configCommonList) {
|
||||
int pid = id++;
|
||||
String ipPort = configCommon.getConfigKey();
|
||||
// 父节点
|
||||
LogMonitorInstanceVO logMonitorInstanceVOParent = new LogMonitorInstanceVO();
|
||||
logMonitorInstanceVOParent.setRawId(configCommon.getId());
|
||||
logMonitorInstanceVOParent.setTreeId(pid);
|
||||
logMonitorInstanceVOParent.setMonitorName(configCommon.getContent());
|
||||
ret.add(logMonitorInstanceVOParent);
|
||||
try {
|
||||
String logData = this.requestLogServer(ipPort, SOP_LIST_ERRORS_PATH);
|
||||
JSONObject jsonObject = JSON.parseObject(logData);
|
||||
if (CODE_SUCCESS.equals(jsonObject.getString("code"))) {
|
||||
int errorTotal = 0;
|
||||
List<LogMonitorInstanceVO> data = JSON.parseArray(jsonObject.getString("data"), LogMonitorInstanceVO.class);
|
||||
for (LogMonitorInstanceVO instanceVO : data) {
|
||||
instanceVO.setTreeId(id++);
|
||||
instanceVO.setParentId(pid);
|
||||
errorTotal += instanceVO.getCount();
|
||||
}
|
||||
ret.addAll(data);
|
||||
logMonitorInstanceVOParent.setCount(errorTotal);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取日志信息出错", e);
|
||||
logMonitorInstanceVOParent.setMonitorName(logMonitorInstanceVOParent.getMonitorName() + "(请求出错)");
|
||||
}
|
||||
}
|
||||
Collections.sort(ret, Comparator.comparing(LogMonitorInstanceVO::getCount));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Api(name = "monitor.log.clear")
|
||||
@ApiDocMethod(description = "清空日志")
|
||||
void clearLog(@NotNull(message = "id不能为空") Long id) {
|
||||
ConfigCommon configCommon = configCommonMapper.getById(id);
|
||||
if (configCommon == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String ipPort = configCommon.getConfigKey();
|
||||
this.requestLogServer(ipPort, SOP_CLEAR_ERRORS_PATH);
|
||||
} catch (Exception e) {
|
||||
throw new BizException("清除失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "monitor.instance.list")
|
||||
@ApiDocMethod(description = "获取已添加的监控实例")
|
||||
List<String> listServiceInstance() {
|
||||
List<ConfigCommon> configCommonList = configCommonMapper.listByColumn("config_group", LOG_MONITOR_INSTANCE);
|
||||
return configCommonList.stream()
|
||||
.map(ConfigCommon::getConfigKey)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Api(name = "monitor.instance.add")
|
||||
@ApiDocMethod(description = "添加监控实例")
|
||||
void addServiceInstance(LogMonitorInstanceAddParam param) {
|
||||
String ipPort = param.getIpPort();
|
||||
this.checkInstance(ipPort);
|
||||
|
||||
Query query = new Query();
|
||||
query.eq("config_group", LOG_MONITOR_INSTANCE)
|
||||
.eq("config_key", ipPort);
|
||||
ConfigCommon rec = configCommonMapper.getByQuery(query);
|
||||
if (rec != null) {
|
||||
throw new BizException("该实例已添加");
|
||||
}
|
||||
ConfigCommon configCommon = new ConfigCommon();
|
||||
configCommon.setConfigGroup(LOG_MONITOR_INSTANCE);
|
||||
configCommon.setConfigKey(ipPort);
|
||||
configCommon.setContent(param.getServiceId() + "(" + ipPort + ")");
|
||||
configCommonMapper.saveIgnoreNull(configCommon);
|
||||
}
|
||||
|
||||
private void checkInstance(String ipPort) {
|
||||
try {
|
||||
String json = this.requestLogServer(ipPort, SOP_LIST_ERRORS_PATH);
|
||||
JSONObject jsonObject = JSON.parseObject(json);
|
||||
if (!CODE_SUCCESS.equals(jsonObject.getString(CODE_KEY))) {
|
||||
log.error("请求结果:{}", json);
|
||||
throw new BizException("添加失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加失败", e);
|
||||
throw new BizException("添加失败");
|
||||
}
|
||||
}
|
||||
|
||||
private String requestLogServer(String ipPort, String path) throws Exception {
|
||||
DefaultMd5Verifier md5Verifier = new DefaultMd5Verifier();
|
||||
Map<String, Object> params = new HashMap<>(16);
|
||||
params.put("time", System.currentTimeMillis());
|
||||
String sign = md5Verifier.buildSign(params, secret);
|
||||
params.put("sign", sign);
|
||||
String query = QueryUtil.buildQueryString(params);
|
||||
path = path.startsWith("/") ? path.substring(1) : path;
|
||||
String url = "http://" + ipPort + "/" + path + "?" + query;
|
||||
ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);
|
||||
if (entity.getStatusCode() != HttpStatus.OK) {
|
||||
throw new IllegalAccessException("无权访问");
|
||||
}
|
||||
return entity.getBody();
|
||||
}
|
||||
|
||||
@Api(name = "monitor.instance.del")
|
||||
@ApiDocMethod(description = "删除监控实例")
|
||||
void delServiceInstance(@NotNull(message = "id不能为空") Long id) {
|
||||
configCommonMapper.deleteById(id);
|
||||
}
|
||||
|
||||
}
|
@@ -1,166 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.MonitorInfoVO;
|
||||
import com.gitee.sop.adminserver.api.service.result.MonitorResult;
|
||||
import com.gitee.sop.adminserver.api.service.result.ServiceInstanceVO;
|
||||
import com.gitee.sop.adminserver.common.QueryUtil;
|
||||
import com.gitee.sop.adminserver.service.ServerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
* @deprecated use com.gitee.sop.adminserver.api.service.MonitorNewApi
|
||||
* @see MonitorNewApi
|
||||
*/
|
||||
@Deprecated
|
||||
//@ApiService
|
||||
@ApiDoc("服务管理-监控")
|
||||
@Slf4j
|
||||
public class MonitorApi {
|
||||
|
||||
private static final String GATEWAY_MONITOR_PATH = "/sop/getMonitorData";
|
||||
|
||||
@Autowired
|
||||
private ServerService serverService;
|
||||
|
||||
@Value("${sop.secret}")
|
||||
private String secret;
|
||||
|
||||
@Api(name = "monitor.data.list")
|
||||
@ApiDocMethod(description = "获取监控数据")
|
||||
public MonitorResult listMonitorData(RouteParam param) {
|
||||
ServiceSearchParam serviceSearchParam = new ServiceSearchParam();
|
||||
serviceSearchParam.setServiceId("sop-gateway");
|
||||
String searchRouteId = param.getRouteId();
|
||||
List<MonitorInfoVO> monitorInfoList = new ArrayList<>();
|
||||
List<ServiceInstanceVO> serviceInstanceVOS = serverService.listService(serviceSearchParam);
|
||||
for (ServiceInstanceVO serviceInstanceVO : serviceInstanceVOS) {
|
||||
if (StringUtils.isBlank(serviceInstanceVO.getInstanceId())) {
|
||||
continue;
|
||||
}
|
||||
String ipPort = serviceInstanceVO.getIpPort();
|
||||
try {
|
||||
String data = QueryUtil.requestServer(ipPort, GATEWAY_MONITOR_PATH, secret);
|
||||
JSONObject jsonObject = JSON.parseObject(data);
|
||||
List<MonitorInfoVO> monitorInfoVOList = this.buildMonitorInfoVO(serviceInstanceVO, jsonObject.getJSONObject("data"));
|
||||
List<MonitorInfoVO> newList = monitorInfoVOList.stream()
|
||||
.filter(monitorInfoVO -> StringUtils.isBlank(searchRouteId)
|
||||
|| StringUtils.containsIgnoreCase(monitorInfoVO.getRouteId(), searchRouteId))
|
||||
.collect(Collectors.toList());
|
||||
monitorInfoList.addAll(newList);
|
||||
} catch (Exception e) {
|
||||
log.error("请求服务失败, ipPort:{}, path:{}", ipPort, GATEWAY_MONITOR_PATH, e);
|
||||
throw new ApiException("请求数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
MonitorResult monitorResult = new MonitorResult();
|
||||
List<MonitorInfoVO> monitorInfoTreeData = this.buildTreeData(monitorInfoList);
|
||||
monitorResult.setMonitorInfoData(monitorInfoTreeData);
|
||||
return monitorResult;
|
||||
}
|
||||
|
||||
private List<MonitorInfoVO> buildTreeData(List<MonitorInfoVO> monitorInfoList) {
|
||||
AtomicInteger id = new AtomicInteger();
|
||||
List<MonitorInfoVO> treeData = new ArrayList<>(8);
|
||||
monitorInfoList.stream()
|
||||
.collect(Collectors.groupingBy(MonitorInfoVO::getRouteId))
|
||||
.forEach((routeId, items) -> {
|
||||
MonitorInfoVO monitorInfoVOTotal = getStatistics(items, id);
|
||||
monitorInfoVOTotal.setId(id.incrementAndGet());
|
||||
treeData.add(monitorInfoVOTotal);
|
||||
});
|
||||
|
||||
Comparator<MonitorInfoVO> comparator = Comparator
|
||||
// 根据错误次数降序
|
||||
.comparing(MonitorInfoVO::getErrorCount).reversed()
|
||||
// 然后根据请求耗时降序
|
||||
.thenComparing(Comparator.comparing(MonitorInfoVO::getAvgTime).reversed());
|
||||
treeData.sort(comparator);
|
||||
return treeData;
|
||||
}
|
||||
|
||||
private MonitorInfoVO getStatistics(List<MonitorInfoVO> children, AtomicInteger id) {
|
||||
long totalRequestDataSize = 0;
|
||||
long totalResponseDataSize = 0;
|
||||
long maxTime = 0;
|
||||
long minTime = 0;
|
||||
long totalTime = 0;
|
||||
long totalCount = 0;
|
||||
long successCount = 0;
|
||||
long errorCount = 0;
|
||||
List<String> errorMsgList = new ArrayList<>();
|
||||
|
||||
String name = null,version = null, serviceId = null;
|
||||
|
||||
for (MonitorInfoVO child : children) {
|
||||
name = child.getName();
|
||||
version = child.getVersion();
|
||||
serviceId = child.getServiceId();
|
||||
|
||||
child.setId(id.incrementAndGet());
|
||||
totalRequestDataSize += child.getTotalRequestDataSize();
|
||||
totalResponseDataSize += child.getTotalResponseDataSize();
|
||||
if (minTime == 0 || child.getMinTime() < minTime) {
|
||||
minTime = child.getMinTime();
|
||||
}
|
||||
if (child.getMaxTime() > maxTime) {
|
||||
maxTime = child.getMaxTime();
|
||||
}
|
||||
totalTime += child.getTotalTime();
|
||||
totalCount += child.getTotalCount();
|
||||
successCount += child.getSuccessCount();
|
||||
errorCount += child.getErrorCount();
|
||||
errorMsgList.addAll(child.getErrorMsgList());
|
||||
}
|
||||
|
||||
MonitorInfoVO total = new MonitorInfoVO();
|
||||
total.setName(name);
|
||||
total.setVersion(version);
|
||||
total.setServiceId(serviceId);
|
||||
total.setErrorCount(errorCount);
|
||||
total.setMaxTime(maxTime);
|
||||
total.setMinTime(minTime);
|
||||
total.setSuccessCount(successCount);
|
||||
total.setTotalCount(totalCount);
|
||||
total.setTotalRequestDataSize(totalRequestDataSize);
|
||||
total.setTotalResponseDataSize(totalResponseDataSize);
|
||||
total.setTotalTime(totalTime);
|
||||
total.setChildren(children);
|
||||
total.setErrorMsgList(errorMsgList);
|
||||
return total;
|
||||
}
|
||||
|
||||
private List<MonitorInfoVO> buildMonitorInfoVO(ServiceInstanceVO serviceInstanceVO, JSONObject monitorData) {
|
||||
Set<String> routeIdList = monitorData.keySet();
|
||||
List<MonitorInfoVO> ret = new ArrayList<>(routeIdList.size());
|
||||
routeIdList.forEach(routeId -> {
|
||||
JSONObject monitorInfo = monitorData.getJSONObject(routeId);
|
||||
MonitorInfoVO monitorInfoVO = monitorInfo.toJavaObject(MonitorInfoVO.class);
|
||||
monitorInfoVO.setInstanceId(serviceInstanceVO.getIpPort());
|
||||
ret.add(monitorInfoVO);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.support.PageEasyui;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.service.param.InstanceMonitorSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.MonitorErrorMsgParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.MonitorInfoErrorSolveParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.MonitorSearchParam;
|
||||
import com.gitee.sop.adminserver.bean.RouteErrorCount;
|
||||
import com.gitee.sop.adminserver.entity.MonitorInfoError;
|
||||
import com.gitee.sop.adminserver.entity.MonitorSummary;
|
||||
import com.gitee.sop.adminserver.mapper.MonitorInfoErrorMapper;
|
||||
import com.gitee.sop.adminserver.mapper.MonitorInfoMapper;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 路由监控
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
public class MonitorNewApi {
|
||||
|
||||
@Autowired
|
||||
private MonitorInfoMapper monitorInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private MonitorInfoErrorMapper monitorInfoErrorMapper;
|
||||
|
||||
@Api(name = "monitornew.data.page")
|
||||
PageInfo<Object> listMonitor(MonitorSearchParam param) {
|
||||
Query query = Query.build(param);
|
||||
query.orderby("errorCount", Sort.DESC)
|
||||
.orderby("avgTime", Sort.DESC);
|
||||
return PageHelper.offsetPage(query.getStart(), query.getLimit())
|
||||
.doSelectPage(() -> monitorInfoMapper.listMonitorSummary(query))
|
||||
.toPageInfo();
|
||||
}
|
||||
|
||||
@Api(name = "monitornew.routeid.data.get")
|
||||
List<MonitorSummary> listInstanceMonitor(InstanceMonitorSearchParam param) {
|
||||
Query query = Query.build(param);
|
||||
query.orderby("errorCount", Sort.DESC)
|
||||
.orderby("avgTime", Sort.DESC);
|
||||
return monitorInfoMapper.listInstanceMonitorInfo(query);
|
||||
}
|
||||
|
||||
private Map<String, Integer> getRouteErrorCount() {
|
||||
List<RouteErrorCount> routeErrorCounts = monitorInfoErrorMapper.listRouteErrorCount();
|
||||
return routeErrorCounts.stream()
|
||||
.collect(Collectors.toMap(RouteErrorCount::getRouteId, RouteErrorCount::getCount));
|
||||
}
|
||||
|
||||
@Api(name = "monitornew.error.page")
|
||||
PageEasyui<MonitorInfoError> listError(MonitorErrorMsgParam param) {
|
||||
Query query = param.toQuery()
|
||||
.orderby("gmt_modified", Sort.DESC);
|
||||
return MapperUtil.queryForEasyuiDatagrid(monitorInfoErrorMapper, query);
|
||||
}
|
||||
|
||||
@Api(name = "monitornew.error.solve")
|
||||
void solve(MonitorInfoErrorSolveParam param) {
|
||||
Query query = Query.build(param);
|
||||
Map<String, Object> set = new HashMap<>(4);
|
||||
set.put("is_deleted", 1);
|
||||
set.put("count", 0);
|
||||
monitorInfoErrorMapper.updateByMap(set, query);
|
||||
}
|
||||
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.sop.adminserver.api.system.param.IspPageParam;
|
||||
import com.gitee.sop.adminserver.api.system.param.IspResourceParam;
|
||||
import com.gitee.sop.adminserver.common.CopyUtil;
|
||||
import com.gitee.sop.adminserver.entity.IspResource;
|
||||
import com.gitee.sop.adminserver.mapper.IspResourceMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
public class ResourceApi {
|
||||
|
||||
public static final byte RESOURCE_TYPE_SDK = (byte) 0;
|
||||
|
||||
@Autowired
|
||||
private IspResourceMapper ispResourceMapper;
|
||||
|
||||
|
||||
@Api(name = "isp.sdk.list")
|
||||
List<IspResource> list(IspPageParam param) {
|
||||
return ispResourceMapper.list(param.toQuery());
|
||||
}
|
||||
|
||||
@Api(name = "isp.sdk.add")
|
||||
void addSdk(IspResourceParam param) {
|
||||
IspResource ispResource = CopyUtil.copyBean(param, IspResource::new);
|
||||
ispResource.setType(RESOURCE_TYPE_SDK);
|
||||
ispResourceMapper.saveIgnoreNull(ispResource);
|
||||
}
|
||||
|
||||
@Api(name = "isp.sdk.update")
|
||||
void updateSdk(IspResourceParam param) {
|
||||
IspResource resource = ispResourceMapper.getById(param.getId());
|
||||
CopyUtil.copyProperties(param, resource);
|
||||
ispResourceMapper.update(resource);
|
||||
}
|
||||
|
||||
@Api(name = "isp.sdk.delete")
|
||||
void deleteSdk(@NotNull Long id) {
|
||||
IspResource resource = ispResourceMapper.getById(id);
|
||||
if (resource != null) {
|
||||
ispResourceMapper.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,259 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.fastmybatis.core.query.Sort;
|
||||
import com.gitee.fastmybatis.core.support.PageEasyui;
|
||||
import com.gitee.fastmybatis.core.util.MapperUtil;
|
||||
import com.gitee.sop.adminserver.api.isv.result.RoleVO;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteDeleteParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RoutePermissionParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteStatusUpdateParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.RouteUpdateParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.RouteVO;
|
||||
import com.gitee.sop.adminserver.bean.RouteConfigDto;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.entity.ConfigRouteBase;
|
||||
import com.gitee.sop.adminserver.entity.ConfigServiceRoute;
|
||||
import com.gitee.sop.adminserver.entity.PermRole;
|
||||
import com.gitee.sop.adminserver.entity.PermRolePermission;
|
||||
import com.gitee.sop.adminserver.entity.RouteRoleDTO;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigRouteBaseMapper;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigServiceRouteMapper;
|
||||
import com.gitee.sop.adminserver.mapper.PermRoleMapper;
|
||||
import com.gitee.sop.adminserver.mapper.PermRolePermissionMapper;
|
||||
import com.gitee.sop.adminserver.service.RouteConfigService;
|
||||
import com.gitee.sop.adminserver.service.RoutePermissionService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("服务管理-路由管理")
|
||||
@Slf4j
|
||||
public class RouteApi {
|
||||
|
||||
@Autowired
|
||||
PermRolePermissionMapper permRolePermissionMapper;
|
||||
|
||||
@Autowired
|
||||
PermRoleMapper permRoleMapper;
|
||||
|
||||
@Autowired
|
||||
ConfigRouteBaseMapper configRouteBaseMapper;
|
||||
|
||||
@Autowired
|
||||
private ConfigServiceRouteMapper configServiceRouteMapper;
|
||||
|
||||
@Autowired
|
||||
RoutePermissionService routePermissionService;
|
||||
|
||||
@Autowired
|
||||
RouteConfigService routeConfigService;
|
||||
|
||||
@ApiDocMethod(description = "路由列表,分页")
|
||||
@Api(name = "route.page")
|
||||
PageEasyui<RouteVO> page(RouteSearchParam form) {
|
||||
Query query = Query.build(form);
|
||||
query.orderby("id", Sort.ASC);
|
||||
PageEasyui<RouteVO> datagrid = MapperUtil.queryForEasyuiDatagrid(configServiceRouteMapper, query, RouteVO.class);
|
||||
List<String> routeIdList = datagrid.getRows()
|
||||
.parallelStream()
|
||||
.map(RouteVO::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (routeIdList.isEmpty()) {
|
||||
return datagrid;
|
||||
}
|
||||
|
||||
Map<String, Byte> routeIdStatusMap = configRouteBaseMapper
|
||||
.list(new Query().in("route_id", routeIdList))
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ConfigRouteBase::getRouteId, ConfigRouteBase::getStatus));
|
||||
|
||||
Map<String, List<RouteRoleDTO>> routeIdRoleMap = permRolePermissionMapper.listRouteRole(routeIdList)
|
||||
.parallelStream()
|
||||
.collect(Collectors.groupingBy(RouteRoleDTO::getRouteId));
|
||||
|
||||
|
||||
datagrid.getRows().forEach(vo -> {
|
||||
String routeId = vo.getId();
|
||||
List<RouteRoleDTO> routeRoleDTOS = routeIdRoleMap.getOrDefault(routeId, Collections.emptyList());
|
||||
vo.setRoles(routeRoleDTOS);
|
||||
Byte status = routeIdStatusMap.getOrDefault(routeId, vo.getStatus());
|
||||
vo.setStatus(status);
|
||||
});
|
||||
|
||||
return datagrid;
|
||||
}
|
||||
|
||||
@Api(name = "route.list", version = "1.2")
|
||||
@ApiDocMethod(description = "路由列表1.2")
|
||||
List<ConfigServiceRoute> listRoute2(RouteSearchParam param) {
|
||||
String serviceId = param.getServiceId();
|
||||
if (StringUtils.isBlank(serviceId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Query query = Query.build(param);
|
||||
return configServiceRouteMapper.list(query);
|
||||
}
|
||||
|
||||
@Api(name = "route.add")
|
||||
@ApiDocMethod(description = "新增路由")
|
||||
void addRoute(RouteAddParam param) {
|
||||
// TODO: 新增路由
|
||||
}
|
||||
|
||||
@Api(name = "route.update")
|
||||
@ApiDocMethod(description = "修改路由")
|
||||
void updateRoute(RouteUpdateParam param) {
|
||||
this.updateRouteConfig(param);
|
||||
}
|
||||
|
||||
@Api(name = "route.status.update")
|
||||
@ApiDocMethod(description = "修改路由状态")
|
||||
void updateRouteStatus(RouteStatusUpdateParam param) {
|
||||
String routeId = param.getId();
|
||||
ConfigRouteBase configRouteBase = configRouteBaseMapper.getByColumn("route_id", routeId);
|
||||
boolean doSave = configRouteBase == null;
|
||||
if (doSave) {
|
||||
configRouteBase = new ConfigRouteBase();
|
||||
configRouteBase.setRouteId(routeId);
|
||||
}
|
||||
configRouteBase.setStatus(param.getStatus());
|
||||
|
||||
int i = doSave ? configRouteBaseMapper.save(configRouteBase)
|
||||
: configRouteBaseMapper.update(configRouteBase);
|
||||
|
||||
if (i > 0) {
|
||||
this.sendMsg(configRouteBase);
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "route.del")
|
||||
@ApiDocMethod(description = "删除路由")
|
||||
void delRoute(RouteDeleteParam param) {
|
||||
// TODO: 删除路由
|
||||
}
|
||||
|
||||
|
||||
private void updateRouteConfig(RouteUpdateParam routeUpdateParam) {
|
||||
String routeId = routeUpdateParam.getId();
|
||||
ConfigRouteBase configRouteBase = configRouteBaseMapper.getByColumn("route_id", routeId);
|
||||
boolean doSave = configRouteBase == null;
|
||||
if (doSave) {
|
||||
configRouteBase = new ConfigRouteBase();
|
||||
configRouteBase.setRouteId(routeId);
|
||||
}
|
||||
configRouteBase.setStatus(routeUpdateParam.getStatus().byteValue());
|
||||
|
||||
int i = doSave ? configRouteBaseMapper.save(configRouteBase)
|
||||
: configRouteBaseMapper.update(configRouteBase);
|
||||
|
||||
if (i > 0) {
|
||||
this.sendMsg(configRouteBase);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMsg(ConfigRouteBase routeDefinition) {
|
||||
RouteConfigDto routeConfigDto = new RouteConfigDto();
|
||||
routeConfigDto.setRouteId(routeDefinition.getRouteId());
|
||||
routeConfigDto.setStatus(routeDefinition.getStatus().intValue());
|
||||
routeConfigService.sendRouteConfigMsg(routeConfigDto);
|
||||
}
|
||||
|
||||
@Api(name = "route.role.get")
|
||||
@ApiDocMethod(description = "获取路由对应的角色", elementClass = RoleVO.class)
|
||||
List<RoleVO> getRouteRole(RouteSearchParam param) {
|
||||
if (StringUtils.isBlank(param.getId())) {
|
||||
throw new BizException("id不能为空");
|
||||
}
|
||||
return this.getRouteRole(param.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由对应的角色
|
||||
*
|
||||
* @param routeIdList routeIdList
|
||||
* @return
|
||||
*/
|
||||
private List<RoleVO> getRouteRole(List<String> routeIdList) {
|
||||
// key:routeId, value: roleCode
|
||||
Map<String, List<String>> routeIdRoleCodeMap = permRolePermissionMapper.list(new Query().in("route_id", routeIdList))
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(PermRolePermission::getRouteId,
|
||||
Collectors.mapping(PermRolePermission::getRoleCode, Collectors.toList())));
|
||||
|
||||
|
||||
return permRolePermissionMapper.list(new Query().in("route_id", routeIdList))
|
||||
.stream()
|
||||
.map(permRolePermission -> {
|
||||
RoleVO vo = new RoleVO();
|
||||
String roleCode = permRolePermission.getRoleCode();
|
||||
PermRole permRole = permRoleMapper.getByColumn("role_code", roleCode);
|
||||
BeanUtils.copyProperties(permRole, vo);
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由对应的角色
|
||||
*
|
||||
* @param id routeId
|
||||
* @return
|
||||
*/
|
||||
private List<RoleVO> getRouteRole(String id) {
|
||||
return permRolePermissionMapper.listByColumn("route_id", id)
|
||||
.stream()
|
||||
.map(permRolePermission -> {
|
||||
RoleVO vo = new RoleVO();
|
||||
String roleCode = permRolePermission.getRoleCode();
|
||||
PermRole permRole = permRoleMapper.getByColumn("role_code", roleCode);
|
||||
BeanUtils.copyProperties(permRole, vo);
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Api(name = "route.role.update")
|
||||
@ApiDocMethod(description = "更新路由对应的角色")
|
||||
public void updateRouteRole(RoutePermissionParam param) {
|
||||
RoutePermissionParam oldRoutePermission = this.buildOldRoutePermission(param.getRouteId());
|
||||
routePermissionService.updateRoutePermission(param);
|
||||
try {
|
||||
routePermissionService.sendRoutePermissionReloadMsg(oldRoutePermission);
|
||||
} catch (Exception e) {
|
||||
log.error("消息推送--路由权限(reload)失败", e);
|
||||
// 回滚
|
||||
routePermissionService.updateRoutePermission(oldRoutePermission);
|
||||
throw new BizException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private RoutePermissionParam buildOldRoutePermission(String routeId) {
|
||||
List<RoleVO> routeRole = this.getRouteRole(routeId);
|
||||
List<String> roleCodeList = routeRole.stream()
|
||||
.map(RoleVO::getRoleCode)
|
||||
.collect(Collectors.toList());
|
||||
RoutePermissionParam routePermissionParam = new RoutePermissionParam();
|
||||
routePermissionParam.setRouteId(routeId);
|
||||
routePermissionParam.setRoleCode(roleCodeList);
|
||||
return routePermissionParam;
|
||||
}
|
||||
|
||||
}
|
@@ -1,227 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service;
|
||||
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceAddParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceGrayConfigParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceIdParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceInstanceParam;
|
||||
import com.gitee.sop.adminserver.api.service.param.ServiceSearchParam;
|
||||
import com.gitee.sop.adminserver.api.service.result.ServiceInfoVo;
|
||||
import com.gitee.sop.adminserver.api.service.result.ServiceInstanceVO;
|
||||
import com.gitee.sop.adminserver.bean.ChannelMsg;
|
||||
import com.gitee.sop.adminserver.bean.MetadataEnum;
|
||||
import com.gitee.sop.adminserver.bean.NacosConfigs;
|
||||
import com.gitee.sop.adminserver.bean.ServiceGrayDefinition;
|
||||
import com.gitee.sop.adminserver.bean.ServiceInstance;
|
||||
import com.gitee.sop.adminserver.common.BizException;
|
||||
import com.gitee.sop.adminserver.common.ChannelOperation;
|
||||
import com.gitee.sop.adminserver.common.StatusEnum;
|
||||
import com.gitee.sop.adminserver.entity.ConfigGray;
|
||||
import com.gitee.sop.adminserver.entity.ConfigGrayInstance;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigGrayInstanceMapper;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigGrayMapper;
|
||||
import com.gitee.sop.adminserver.mapper.ConfigServiceRouteMapper;
|
||||
import com.gitee.sop.adminserver.service.ConfigPushService;
|
||||
import com.gitee.sop.adminserver.service.RegistryService;
|
||||
import com.gitee.sop.adminserver.service.ServerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("服务管理-服务列表")
|
||||
@Slf4j
|
||||
public class ServiceApi {
|
||||
|
||||
|
||||
@Autowired
|
||||
private RegistryService registryService;
|
||||
|
||||
@Autowired
|
||||
private ServerService serverService;
|
||||
|
||||
@Autowired
|
||||
private ConfigGrayMapper configGrayMapper;
|
||||
|
||||
@Autowired
|
||||
private ConfigGrayInstanceMapper configGrayInstanceMapper;
|
||||
|
||||
@Autowired
|
||||
private ConfigServiceRouteMapper configServiceRouteMapper;
|
||||
|
||||
@Autowired
|
||||
private ConfigPushService configPushService;
|
||||
|
||||
@Api(name = "registry.service.list")
|
||||
@ApiDocMethod(description = "路由配置中的服务列表", elementClass = String.class)
|
||||
List<String> listServiceInfo(ServiceSearchParam param) {
|
||||
List<String> allServiceId = configServiceRouteMapper.listAllServiceId();
|
||||
return allServiceId
|
||||
.stream()
|
||||
.filter(serviceId -> {
|
||||
if (StringUtils.isBlank(param.getServiceId())) {
|
||||
return true;
|
||||
} else {
|
||||
return serviceId.contains(param.getServiceId());
|
||||
}
|
||||
})
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Api(name = "service.custom.add")
|
||||
@ApiDocMethod(description = "添加服务")
|
||||
void addService(ServiceAddParam param) {
|
||||
throw new BizException("该功能已下线");
|
||||
}
|
||||
|
||||
@Api(name = "service.custom.del")
|
||||
@ApiDocMethod(description = "删除自定义服务")
|
||||
void delService(ServiceSearchParam param) {
|
||||
throw new BizException("该功能已下线");
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.list")
|
||||
@ApiDocMethod(description = "获取注册中心的服务列表", elementClass = ServiceInfoVo.class)
|
||||
List<ServiceInstanceVO> listService(ServiceSearchParam param) {
|
||||
return serverService.listService(param);
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.offline")
|
||||
@ApiDocMethod(description = "服务禁用")
|
||||
void serviceOffline(ServiceInstanceParam param) {
|
||||
try {
|
||||
registryService.offlineInstance(param.buildServiceInstance());
|
||||
} catch (Exception e) {
|
||||
log.error("服务禁用失败,param:{}", param, e);
|
||||
throw new BizException("服务禁用失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.online")
|
||||
@ApiDocMethod(description = "服务启用")
|
||||
void serviceOnline(ServiceInstanceParam param) throws IOException {
|
||||
try {
|
||||
registryService.onlineInstance(param.buildServiceInstance());
|
||||
} catch (Exception e) {
|
||||
log.error("服务启用失败,param:{}", param, e);
|
||||
throw new BizException("服务启用失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.env.pre.open")
|
||||
@ApiDocMethod(description = "预发布")
|
||||
void serviceEnvPre(ServiceInstanceParam param) throws IOException {
|
||||
try {
|
||||
MetadataEnum envPre = MetadataEnum.ENV_PRE;
|
||||
registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue());
|
||||
} catch (Exception e) {
|
||||
log.error("预发布失败,param:{}", param, e);
|
||||
throw new BizException("预发布失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "service.gray.config.get")
|
||||
@ApiDocMethod(description = "灰度配置--获取")
|
||||
ConfigGray serviceEnvGrayConfigGet(ServiceIdParam param) throws IOException {
|
||||
return this.getConfigGray(param.getServiceId());
|
||||
}
|
||||
|
||||
@Api(name = "service.gray.config.save")
|
||||
@ApiDocMethod(description = "灰度配置--保存")
|
||||
void serviceEnvGrayConfigSave(ServiceGrayConfigParam param) throws IOException {
|
||||
String serviceId = param.getServiceId().toLowerCase();
|
||||
ConfigGray configGray = configGrayMapper.getByColumn("service_id", serviceId);
|
||||
if (configGray == null) {
|
||||
configGray = new ConfigGray();
|
||||
configGray.setServiceId(serviceId);
|
||||
configGray.setNameVersionContent(param.getNameVersionContent());
|
||||
configGray.setUserKeyContent(param.getUserKeyContent());
|
||||
configGrayMapper.save(configGray);
|
||||
} else {
|
||||
configGray.setNameVersionContent(param.getNameVersionContent());
|
||||
configGray.setUserKeyContent(param.getUserKeyContent());
|
||||
configGrayMapper.update(configGray);
|
||||
}
|
||||
this.sendServiceGrayMsg(serviceId, ChannelOperation.GRAY_USER_KEY_SET);
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.env.gray.open")
|
||||
@ApiDocMethod(description = "开启灰度发布")
|
||||
void serviceEnvGray(ServiceInstanceParam param) throws IOException {
|
||||
String serviceId = param.getServiceId().toLowerCase();
|
||||
ConfigGray configGray = this.getConfigGray(serviceId);
|
||||
if (configGray == null) {
|
||||
throw new BizException("请先设置灰度参数");
|
||||
}
|
||||
try {
|
||||
MetadataEnum envPre = MetadataEnum.ENV_GRAY;
|
||||
registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue());
|
||||
|
||||
String instanceId = param.getInstanceId();
|
||||
|
||||
ConfigGrayInstance configGrayInstance = configGrayInstanceMapper.getByColumn("instance_id", instanceId);
|
||||
if (configGrayInstance == null) {
|
||||
configGrayInstance = new ConfigGrayInstance();
|
||||
configGrayInstance.setServiceId(serviceId);
|
||||
configGrayInstance.setInstanceId(instanceId);
|
||||
configGrayInstance.setStatus(StatusEnum.STATUS_ENABLE.getStatus());
|
||||
configGrayInstanceMapper.save(configGrayInstance);
|
||||
} else {
|
||||
configGrayInstance.setStatus(StatusEnum.STATUS_ENABLE.getStatus());
|
||||
configGrayInstance.setServiceId(serviceId);
|
||||
configGrayInstanceMapper.update(configGrayInstance);
|
||||
}
|
||||
this.sendServiceGrayMsg(instanceId, serviceId, ChannelOperation.GRAY_USER_KEY_OPEN);
|
||||
} catch (Exception e) {
|
||||
log.error("灰度发布失败,param:{}", param, e);
|
||||
throw new BizException("灰度发布失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
@Api(name = "service.instance.env.online")
|
||||
@ApiDocMethod(description = "上线")
|
||||
void serviceEnvOnline(ServiceInstance param) throws IOException {
|
||||
try {
|
||||
MetadataEnum envPre = MetadataEnum.ENV_ONLINE;
|
||||
registryService.setMetadata(param, envPre.getKey(), envPre.getValue());
|
||||
|
||||
ConfigGrayInstance configGrayInstance = configGrayInstanceMapper.getByColumn("instance_id", param.getInstanceId());
|
||||
if (configGrayInstance != null) {
|
||||
configGrayInstance.setStatus(StatusEnum.STATUS_DISABLE.getStatus());
|
||||
configGrayInstanceMapper.update(configGrayInstance);
|
||||
this.sendServiceGrayMsg(param.getInstanceId(), param.getServiceId().toLowerCase(), ChannelOperation.GRAY_USER_KEY_CLOSE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上线失败,param:{}", param, e);
|
||||
throw new BizException("上线失败,请查看日志");
|
||||
}
|
||||
}
|
||||
|
||||
private void sendServiceGrayMsg(String serviceId, ChannelOperation channelOperation) {
|
||||
this.sendServiceGrayMsg(null, serviceId, channelOperation);
|
||||
}
|
||||
|
||||
private void sendServiceGrayMsg(String instanceId, String serviceId, ChannelOperation channelOperation) {
|
||||
ServiceGrayDefinition serviceGrayDefinition = new ServiceGrayDefinition();
|
||||
serviceGrayDefinition.setInstanceId(instanceId);
|
||||
serviceGrayDefinition.setServiceId(serviceId);
|
||||
ChannelMsg channelMsg = new ChannelMsg(channelOperation, serviceGrayDefinition);
|
||||
configPushService.publishConfig(NacosConfigs.DATA_ID_GRAY, NacosConfigs.GROUP_CHANNEL, channelMsg);
|
||||
}
|
||||
|
||||
private ConfigGray getConfigGray(String serviceId) {
|
||||
return configGrayMapper.getByColumn("service_id", serviceId);
|
||||
}
|
||||
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:config_ip_black
|
||||
* 备注:IP黑名单
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ConfigIpBlackForm {
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** ip, 数据库字段:ip */
|
||||
@NotBlank(message = "不能为空")
|
||||
@Length(max = 30, message = "ip长度太长")
|
||||
private String ip;
|
||||
|
||||
/** 备注, 数据库字段:remark */
|
||||
@Length(max = 100, message = "备注长度太长")
|
||||
private String remark;
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ConfigIpBlacklistPageParam extends PageParam {
|
||||
@ApiDocField(description = "IP")
|
||||
@Condition(operator = Operator.like)
|
||||
private String ip;
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class InstanceMonitorSearchParam {
|
||||
@Condition(column = "t.route_id")
|
||||
private String routeId;
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LimitNewAddParam {
|
||||
/** 路由id, 数据库字段:route_id */
|
||||
@ApiDocField(description = "routeId")
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey")
|
||||
private String appKey;
|
||||
|
||||
/** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */
|
||||
@ApiDocField(description = "limitIp")
|
||||
private String limitIp;
|
||||
|
||||
@ApiDocField(description = "serviceId")
|
||||
@NotBlank(message = "serviceId can not null")
|
||||
private String serviceId;
|
||||
|
||||
/** 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type */
|
||||
@ApiDocField(description = "限流策略,1:窗口策略,2:令牌桶策略")
|
||||
@NotNull(message = "limitType不能为空")
|
||||
private Byte limitType;
|
||||
|
||||
/** 每秒可处理请求数, 数据库字段:exec_count_per_second */
|
||||
@ApiDocField(description = "每秒可处理请求数")
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/** 限流持续时间,默认1秒,即每durationSeconds秒允许多少请求(当limit_type=1时有效) */
|
||||
@ApiDocField(description = "限流持续时间,默认1秒,即每durationSeconds秒允许多少请求(当limit_type=1时有效")
|
||||
@NotNull(message = "durationSeconds不能为空")
|
||||
@Min(value = 1, message = "durationSeconds最小是1")
|
||||
private Integer durationSeconds;
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
@Length(max = 64, message = "limitCode长度不能超过64")
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
@Length(max = 100, message = "limitMsg长度不能超过100")
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
@ApiDocField(description = "令牌桶容量")
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/** 1:开启,0关闭, 数据库字段:limit_status */
|
||||
@ApiDocField(description = "1:开启,0关闭")
|
||||
@NotNull(message = "limitStatus不能为空")
|
||||
private Byte limitStatus;
|
||||
|
||||
@ApiDocField(description = "排序字段")
|
||||
@NotNull(message = "orderIndex不能为空")
|
||||
@Min(value = 0, message = "orderIndex必须大于等于0")
|
||||
private Integer orderIndex;
|
||||
|
||||
@ApiDocField(description = "备注")
|
||||
@Length(max = 128, message = "备注不能超过128")
|
||||
private String remark;
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class LimitNewParam extends PageParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
@Condition(operator = Operator.like)
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey")
|
||||
@Condition(operator = Operator.like)
|
||||
private String appKey;
|
||||
|
||||
/** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */
|
||||
@ApiDocField(description = "限流ip,多个用英文逗号隔开")
|
||||
@Condition(operator = Operator.like)
|
||||
private String limitIp;
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LimitNewUpdateParam {
|
||||
@ApiDocField(description = "id")
|
||||
@NotNull(message = "id can not null")
|
||||
@Min(value = 1, message = "id不正确")
|
||||
private Long id;
|
||||
|
||||
/** 路由id, 数据库字段:route_id */
|
||||
@ApiDocField(description = "routeId")
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey")
|
||||
private String appKey;
|
||||
|
||||
/** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */
|
||||
@ApiDocField(description = "limitIp")
|
||||
private String limitIp;
|
||||
|
||||
@ApiDocField(description = "serviceId")
|
||||
@NotBlank(message = "serviceId can not null")
|
||||
private String serviceId;
|
||||
|
||||
/** 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type */
|
||||
@ApiDocField(description = "限流策略,1:窗口策略,2:令牌桶策略")
|
||||
@NotNull(message = "limitType不能为空")
|
||||
private Byte limitType;
|
||||
|
||||
/** 每秒可处理请求数, 数据库字段:exec_count_per_second */
|
||||
@ApiDocField(description = "每秒可处理请求数")
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/** 限流持续时间,默认1秒,即每durationSeconds秒允许多少请求(当limit_type=1时有效) */
|
||||
@ApiDocField(description = "限流持续时间,默认1秒,即每durationSeconds秒允许多少请求(当limit_type=1时有效")
|
||||
@NotNull(message = "durationSeconds不能为空")
|
||||
@Min(value = 1, message = "durationSeconds最小是1")
|
||||
private Integer durationSeconds;
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
@Length(max = 64, message = "limitCode长度不能超过64")
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
@Length(max = 100, message = "limitMsg长度不能超过100")
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
@ApiDocField(description = "令牌桶容量")
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/** 1:开启,0关闭, 数据库字段:limit_status */
|
||||
@ApiDocField(description = "1:开启,0关闭")
|
||||
@NotNull(message = "limitStatus不能为空")
|
||||
private Byte limitStatus;
|
||||
|
||||
@ApiDocField(description = "排序字段")
|
||||
@NotNull(message = "orderIndex不能为空")
|
||||
@Min(value = 0, message = "orderIndex必须大于等于0")
|
||||
private Integer orderIndex;
|
||||
|
||||
@ApiDocField(description = "备注")
|
||||
@Length(max = 128, message = "备注不能超过128")
|
||||
private String remark;
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LimitParam {
|
||||
@ApiDocField(description = "routeId")
|
||||
@NotBlank(message = "routeId can not null")
|
||||
private String routeId;
|
||||
|
||||
@ApiDocField(description = "serviceId")
|
||||
@NotBlank(message = "serviceId can not null")
|
||||
private String serviceId;
|
||||
|
||||
/** 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type */
|
||||
@ApiDocField(description = "限流策略,1:窗口策略,2:令牌桶策略")
|
||||
@NotNull
|
||||
private Byte limitType;
|
||||
|
||||
/** 每秒可处理请求数, 数据库字段:exec_count_per_second */
|
||||
@ApiDocField(description = "每秒可处理请求数")
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
@ApiDocField(description = "令牌桶容量")
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/** 1:开启,0关闭, 数据库字段:limit_status */
|
||||
@ApiDocField(description = "1:开启,0关闭")
|
||||
@NotNull(message = "limitStatus不能为空")
|
||||
private Byte limitStatus;
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LogMonitorInstanceAddParam {
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@NotBlank(message = "ipPort不能为空")
|
||||
private String ipPort;
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class MonitorErrorMsgParam extends PageParam {
|
||||
@NotBlank(message = "routeId不能为空")
|
||||
private String routeId;
|
||||
|
||||
@Condition(ignoreEmptyString = true)
|
||||
private String instanceId;
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class MonitorInfoErrorSolveParam {
|
||||
/** 错误id,md5(error_msg), 数据库字段:error_id */
|
||||
@NotBlank
|
||||
@Condition(index = 1)
|
||||
private String errorId;
|
||||
|
||||
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class MonitorSearchParam extends PageParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@Condition(column = "service_id", operator = Operator.like, ignoreEmptyString = true)
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
@Condition(column = "route_id", operator = Operator.like, ignoreEmptyString = true)
|
||||
private String routeId;
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteAddParam {
|
||||
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
@Length(max = 100, message = "serviceId长度不能超过100")
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 接口名
|
||||
*/
|
||||
@NotBlank(message = "接口名不能为空")
|
||||
@Length(max = 100, message = "name长度不能超过100")
|
||||
@ApiDocField(description = "接口名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
@NotBlank(message = "版本号不能为空")
|
||||
@Length(max = 100, message = "version长度不能超过100")
|
||||
@ApiDocField(description = "版本号")
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
*/
|
||||
@NotBlank(message = "uri不能为空")
|
||||
@Length(max = 100, message = "uri长度不能超过100")
|
||||
@ApiDocField(description = "路由uri")
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* uri后面跟的path
|
||||
*/
|
||||
@ApiDocField(description = "路由path")
|
||||
@Length(max = 100, message = "path长度不能超过100")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否忽略验证,业务参数验证除外
|
||||
*/
|
||||
@ApiDocField(description = "是否忽略验证,业务参数验证除外,1:忽略,0:不忽略")
|
||||
private Integer ignoreValidate;
|
||||
|
||||
/**
|
||||
* 合并结果,统一格式输出
|
||||
*/
|
||||
@ApiDocField(description = "合并结果,统一格式输出,1:合并,2:不合并")
|
||||
private Integer mergeResult;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull
|
||||
@ApiDocField(description = "状态,0:审核,1:启用,2:禁用")
|
||||
private Integer status;
|
||||
|
||||
@ApiDocField(description = "是否是自定义路由,1:是,0:否")
|
||||
private Integer custom;
|
||||
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteDeleteParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RouteParam {
|
||||
private String routeId;
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RoutePermissionParam {
|
||||
@ApiDocField(description = "routeId", required = true)
|
||||
@NotBlank(message = "routeId不能为空")
|
||||
private String routeId;
|
||||
|
||||
@ApiDocField(description = "角色")
|
||||
private List<String> roleCode;
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.fastmybatis.core.query.Operator;
|
||||
import com.gitee.fastmybatis.core.query.annotation.Condition;
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteSearchParam extends PageParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
@Condition(column = "id", operator = Operator.like)
|
||||
private String id;
|
||||
|
||||
@ApiDocField(description = "是否授权接口,1:是")
|
||||
@Condition(ignoreValue = "0")
|
||||
private Integer permission;
|
||||
|
||||
@ApiDocField(description = "是否需要token接口,1:是")
|
||||
@Condition(ignoreValue = "0")
|
||||
private Integer needToken;
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteStatusUpdateParam {
|
||||
|
||||
/**
|
||||
* 路由的Id
|
||||
*/
|
||||
@NotBlank(message = "id不能为空")
|
||||
@ApiDocField(description = "路由id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull
|
||||
@ApiDocField(description = "状态,0:审核,1:启用,2:禁用")
|
||||
private Byte status;
|
||||
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteUpdateParam {
|
||||
|
||||
/**
|
||||
* 路由的Id
|
||||
*/
|
||||
@NotBlank(message = "id不能为空")
|
||||
@ApiDocField(description = "路由id")
|
||||
private String id;
|
||||
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
@Length(max = 100, message = "serviceId长度不能超过100")
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
*/
|
||||
@NotBlank(message = "uri不能为空")
|
||||
@Length(max = 100, message = "uri长度不能超过100")
|
||||
@ApiDocField(description = "路由uri")
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* uri后面跟的path
|
||||
*/
|
||||
@ApiDocField(description = "路由path")
|
||||
@Length(max = 100, message = "path长度不能超过100")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否忽略验证,业务参数验证除外
|
||||
*/
|
||||
@ApiDocField(description = "是否忽略验证,业务参数验证除外,1:忽略,0:不忽略")
|
||||
private Integer ignoreValidate;
|
||||
|
||||
/**
|
||||
* 合并结果,统一格式输出
|
||||
*/
|
||||
@ApiDocField(description = "合并结果,统一格式输出,1:合并,2:不合并")
|
||||
private Integer mergeResult;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@NotNull
|
||||
@ApiDocField(description = "状态,0:审核,1:启用,2:禁用")
|
||||
private Integer status;
|
||||
|
||||
@ApiDocField(description = "是否是自定义路由,1:是,0:否")
|
||||
private Integer custom;
|
||||
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ServiceAddParam {
|
||||
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@Length(max = 100, message = "长度不能超过100")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceGrayConfigParam {
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "灰度发布用户,多个用英文逗号隔开")
|
||||
@NotBlank(message = "灰度发布用户不能为空")
|
||||
private String userKeyContent;
|
||||
|
||||
@ApiDocField(description = "灰度发布接口名版本号如:order.get1.0=1.2,多个用英文逗号隔开")
|
||||
@NotBlank(message = "灰度发布接口名版本号不能为空")
|
||||
private String nameVersionContent;
|
||||
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceIdParam {
|
||||
@ApiDocField(description = "serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ServiceInstanceGrayParam extends ServiceInstanceParam {
|
||||
|
||||
@ApiDocField(description = "灰度发布用户,多个用英文逗号隔开")
|
||||
@NotBlank(message = "灰度发布用户不能为空")
|
||||
private String userKeyContent;
|
||||
|
||||
@ApiDocField(description = "灰度发布接口名版本号如:order.get1.0=1.2,多个用英文逗号隔开")
|
||||
@NotBlank(message = "灰度发布接口名版本号不能为空")
|
||||
private String nameVersionContent;
|
||||
|
||||
@ApiDocField(description = "是否仅更新灰度用户")
|
||||
private Boolean onlyUpdateGrayUserkey;
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import com.gitee.easyopen.util.CopyUtil;
|
||||
import com.gitee.sop.adminserver.bean.ServiceInstance;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceInstanceParam {
|
||||
@ApiDocField(description = "serviceId")
|
||||
@NotBlank(message = "serviceId不能为空")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "instanceId")
|
||||
@NotBlank(message = "instanceId不能为空")
|
||||
private String instanceId;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
@ApiDocField(description = "ip")
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* port
|
||||
*/
|
||||
@ApiDocField(description = "port")
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* 服务状态,UP:已上线,OUT_OF_SERVICE:已下线
|
||||
*/
|
||||
@ApiDocField(description = "status")
|
||||
private String status;
|
||||
|
||||
|
||||
public ServiceInstance buildServiceInstance() {
|
||||
ServiceInstance serviceInstance = new ServiceInstance();
|
||||
CopyUtil.copyPropertiesIgnoreNull(this, serviceInstance);
|
||||
return serviceInstance;
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ServiceSearchParam {
|
||||
|
||||
@ApiDocField(description = "服务名serviceId")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "instanceId")
|
||||
private String instanceId;
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:config_ip_black
|
||||
* 备注:IP黑名单
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ConfigIpBlacklistVO {
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** ip, 数据库字段:ip */
|
||||
private String ip;
|
||||
|
||||
/** 备注, 数据库字段:remark */
|
||||
private String remark;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -1,82 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LimitNewVO {
|
||||
/** 路由id, 数据库字段:route_id */
|
||||
@ApiDocField(description = "路由id")
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:app_key */
|
||||
@ApiDocField(description = "appKey")
|
||||
private String appKey;
|
||||
|
||||
/** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */
|
||||
@ApiDocField(description = "限流ip,多个用英文逗号隔开")
|
||||
private String limitIp;
|
||||
|
||||
@ApiDocField(description = "限流key")
|
||||
private String limitKey;
|
||||
|
||||
/**
|
||||
* 接口名
|
||||
*/
|
||||
@ApiDocField(description = "接口名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
@ApiDocField(description = "版本号")
|
||||
private String version;
|
||||
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type
|
||||
*/
|
||||
@ApiDocField(description = "限流策略,1:窗口策略,2:令牌桶策略")
|
||||
private Byte limitType;
|
||||
|
||||
/**
|
||||
* 每秒可处理请求数, 数据库字段:exec_count_per_second
|
||||
*/
|
||||
@ApiDocField(description = "每秒可处理请求数")
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/**
|
||||
* 返回的错误码, 数据库字段:limit_code
|
||||
*/
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
private String limitCode;
|
||||
|
||||
/**
|
||||
* 返回的错误信息, 数据库字段:limit_msg
|
||||
*/
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
private String limitMsg;
|
||||
|
||||
/**
|
||||
* 令牌桶容量, 数据库字段:token_bucket_count
|
||||
*/
|
||||
@ApiDocField(description = "令牌桶容量")
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/**
|
||||
* 1:开启,0关闭, 数据库字段:limit_status
|
||||
*/
|
||||
@ApiDocField(description = "1:开启,0关闭")
|
||||
private Byte limitStatus;
|
||||
|
||||
/** 顺序,值小的优先执行, 数据库字段:order_index */
|
||||
@ApiDocField(description = "排序字段")
|
||||
private Integer orderIndex;
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LimitVO {
|
||||
@ApiDocField(description = "是否存在记录")
|
||||
private Integer hasRecord;
|
||||
|
||||
@ApiDocField(description = "路由id")
|
||||
private String routeId;
|
||||
|
||||
/**
|
||||
* 接口名
|
||||
*/
|
||||
@ApiDocField(description = "接口名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
@ApiDocField(description = "版本号")
|
||||
private String version;
|
||||
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type
|
||||
*/
|
||||
@ApiDocField(description = "限流策略,1:窗口策略,2:令牌桶策略")
|
||||
private Byte limitType;
|
||||
|
||||
/**
|
||||
* 每秒可处理请求数, 数据库字段:exec_count_per_second
|
||||
*/
|
||||
@ApiDocField(description = "每秒可处理请求数")
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/**
|
||||
* 返回的错误码, 数据库字段:limit_code
|
||||
*/
|
||||
@ApiDocField(description = "返回的错误码")
|
||||
private String limitCode;
|
||||
|
||||
/**
|
||||
* 返回的错误信息, 数据库字段:limit_msg
|
||||
*/
|
||||
@ApiDocField(description = "返回的错误信息")
|
||||
private String limitMsg;
|
||||
|
||||
/**
|
||||
* 令牌桶容量, 数据库字段:token_bucket_count
|
||||
*/
|
||||
@ApiDocField(description = "令牌桶容量")
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/**
|
||||
* 1:开启,0关闭, 数据库字段:limit_status
|
||||
*/
|
||||
@ApiDocField(description = "1:开启,0关闭")
|
||||
private Byte limitStatus;
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class LogMonitorInstanceVO {
|
||||
private String id;
|
||||
private int treeId;
|
||||
/** 表主键 */
|
||||
private long rawId;
|
||||
private String name;
|
||||
private String version;
|
||||
private String serviceId;
|
||||
private String errorMsg;
|
||||
private long count;
|
||||
|
||||
private int parentId;
|
||||
private String monitorName;
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class MonitorInfoErrorMsgResult {
|
||||
|
||||
private String routeId;
|
||||
|
||||
private String errorId;
|
||||
|
||||
/** 错误信息, 数据库字段:error_msg */
|
||||
private String errorMsg;
|
||||
|
||||
private Integer errorStatus;
|
||||
|
||||
private Integer count;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -1,83 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 每个接口 总调用流量,最大时间,最小时间,总时长,平均时长,调用次数,成功次数,失败次数,错误查看。
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class MonitorInfoVO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
/**
|
||||
* 接口名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
private String version;
|
||||
/**
|
||||
* serviceId
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 请求耗时最长时间
|
||||
*/
|
||||
private Long maxTime;
|
||||
/**
|
||||
* 请求耗时最小时间
|
||||
*/
|
||||
private Long minTime;
|
||||
/**
|
||||
* 总时长
|
||||
*/
|
||||
private Long totalTime;
|
||||
/**
|
||||
* 总调用次数
|
||||
*/
|
||||
private Long totalCount;
|
||||
/**
|
||||
* 成功次数
|
||||
*/
|
||||
private Long successCount;
|
||||
/**
|
||||
* 失败次数(业务主动抛出的异常算作成功,如参数校验,未知的错误算失败)
|
||||
*/
|
||||
private Long errorCount;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private List<String> errorMsgList;
|
||||
/**
|
||||
* 总请求数据量
|
||||
*/
|
||||
private Long totalRequestDataSize;
|
||||
/**
|
||||
* 总返回数据量
|
||||
*/
|
||||
private Long totalResponseDataSize;
|
||||
/**
|
||||
* 实例id
|
||||
*/
|
||||
private List<MonitorInfoVO> children;
|
||||
|
||||
public String getRouteId() {
|
||||
return name + version;
|
||||
}
|
||||
|
||||
/**
|
||||
* 平均时长,总时长/总调用次数
|
||||
* @return 返回平均时长
|
||||
*/
|
||||
public long getAvgTime() {
|
||||
return totalTime/totalCount;
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class MonitorResult {
|
||||
private List<MonitorInfoVO> monitorInfoData;
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RouteServiceInfo {
|
||||
@ApiDocField(description = "serviceId")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
@ApiDocField(description = "修改时间")
|
||||
private String updateTime;
|
||||
|
||||
@ApiDocField(description = "描述")
|
||||
private String description;
|
||||
|
||||
/** 是否是自定义服务,1:是,0:否 */
|
||||
@ApiDocField(description = "是否是自定义服务,1:是,0:否")
|
||||
private Integer custom;
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.gitee.sop.adminserver.entity.RouteRoleDTO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteVO {
|
||||
|
||||
/** 数据库字段:id */
|
||||
private String id;
|
||||
|
||||
/** 数据库字段:service_id */
|
||||
private String serviceId;
|
||||
|
||||
/** 接口名, 数据库字段:name */
|
||||
private String name;
|
||||
|
||||
/** 版本号, 数据库字段:version */
|
||||
private String version;
|
||||
|
||||
/** 路由断言(SpringCloudGateway专用), 数据库字段:predicates */
|
||||
private String predicates;
|
||||
|
||||
/** 路由过滤器(SpringCloudGateway专用), 数据库字段:filters */
|
||||
private String filters;
|
||||
|
||||
/** 路由规则转发的目标uri, 数据库字段:uri */
|
||||
private String uri;
|
||||
|
||||
/** uri后面跟的path, 数据库字段:path */
|
||||
private String path;
|
||||
|
||||
/** 路由执行的顺序, 数据库字段:order */
|
||||
private Integer order;
|
||||
|
||||
/** 是否忽略验证,业务参数验证除外, 数据库字段:ignore_validate */
|
||||
private Byte ignoreValidate;
|
||||
|
||||
/** 状态,0:待审核,1:启用,2:禁用, 数据库字段:status */
|
||||
private Byte status;
|
||||
|
||||
/** 是否合并结果, 数据库字段:merge_result */
|
||||
private Byte mergeResult;
|
||||
|
||||
/** 是否需要token, 数据库字段:need_token */
|
||||
private Byte needToken;
|
||||
|
||||
/** 是否需要授权才能访问, 数据库字段:permission */
|
||||
private Byte permission;
|
||||
|
||||
private List<RouteRoleDTO> roles;
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceInfoVo {
|
||||
@ApiDocField(description = "id")
|
||||
private Integer id;
|
||||
|
||||
@ApiDocField(description = "服务名称(serviceId)")
|
||||
private String name;
|
||||
|
||||
@ApiDocField(description = "instanceId")
|
||||
private String instanceId;
|
||||
|
||||
@ApiDocField(description = "ip")
|
||||
private String ipAddr;
|
||||
|
||||
@ApiDocField(description = "端口")
|
||||
private String serverPort;
|
||||
|
||||
@ApiDocField(description = "status,服务状态,UP:已上线,OUT_OF_SERVICE:已下线")
|
||||
private String status;
|
||||
|
||||
@ApiDocField(description = "statusPageUrl")
|
||||
private String statusPageUrl;
|
||||
|
||||
@ApiDocField(description = "healthCheckUrl")
|
||||
private String healthCheckUrl;
|
||||
|
||||
@ApiDocField(description = "最后更新时间")
|
||||
private String lastUpdatedTimestamp;
|
||||
|
||||
@ApiDocField(description = "parentId")
|
||||
private Integer parentId;
|
||||
|
||||
public String getServiceId() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||
public Date getUpdateTime() {
|
||||
if (StringUtils.isBlank(lastUpdatedTimestamp)) {
|
||||
return null;
|
||||
}
|
||||
return new Date(Long.valueOf(lastUpdatedTimestamp));
|
||||
}
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.service.result;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceInstanceVO {
|
||||
@ApiDocField(description = "id")
|
||||
private Integer id;
|
||||
|
||||
@ApiDocField(description = "服务名称(serviceId)")
|
||||
private String serviceId;
|
||||
|
||||
@ApiDocField(description = "instanceId")
|
||||
private String instanceId;
|
||||
|
||||
@ApiDocField(description = "ipPort")
|
||||
private String ipPort;
|
||||
|
||||
@ApiDocField(description = "ip")
|
||||
private String ip;
|
||||
|
||||
@ApiDocField(description = "port")
|
||||
private int port;
|
||||
|
||||
@ApiDocField(description = "status,服务状态,UP:已上线,OUT_OF_SERVICE:已下线")
|
||||
private String status;
|
||||
|
||||
@ApiDocField(description = "最后更新时间")
|
||||
private String updateTime;
|
||||
|
||||
@ApiDocField(description = "parentId")
|
||||
private Integer parentId;
|
||||
|
||||
@ApiDocField(description = "metadata")
|
||||
private Map<String, String> metadata;
|
||||
|
||||
public String getIpPort() {
|
||||
return ip != null && port > 0 ? ip + ":" + port : "";
|
||||
}
|
||||
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system;
|
||||
|
||||
import com.gitee.easyopen.ApiContext;
|
||||
import com.gitee.easyopen.annotation.Api;
|
||||
import com.gitee.easyopen.annotation.ApiService;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||
import com.gitee.easyopen.session.SessionManager;
|
||||
import com.gitee.fastmybatis.core.query.Query;
|
||||
import com.gitee.sop.adminserver.api.system.param.LoginForm;
|
||||
import com.gitee.sop.adminserver.api.system.result.AdminUserInfoVO;
|
||||
import com.gitee.sop.adminserver.common.AdminErrors;
|
||||
import com.gitee.sop.adminserver.common.WebContext;
|
||||
import com.gitee.sop.adminserver.entity.AdminUserInfo;
|
||||
import com.gitee.sop.adminserver.mapper.AdminUserInfoMapper;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@ApiService
|
||||
@ApiDoc("系统接口")
|
||||
public class SystemApi {
|
||||
|
||||
|
||||
public static final int STATUS_FORBIDDEN = 2;
|
||||
@Autowired
|
||||
AdminUserInfoMapper adminUserInfoMapper;
|
||||
|
||||
@Api(name = "nologin.admin.login")
|
||||
@ApiDocMethod(description = "用户登录")
|
||||
String adminLogin(LoginForm param) {
|
||||
String username = param.getUsername();
|
||||
String password = param.getPassword();
|
||||
password = DigestUtils.md5Hex(username + password + username);
|
||||
|
||||
Query query = new Query()
|
||||
.eq("username", username)
|
||||
.eq("password", password);
|
||||
AdminUserInfo user = adminUserInfoMapper.getByQuery(query);
|
||||
|
||||
if (user == null) {
|
||||
throw AdminErrors.ERROR_USERNAME_PWD.getException();
|
||||
} else {
|
||||
if (user.getStatus() == STATUS_FORBIDDEN) {
|
||||
throw AdminErrors.USER_FORBIDDEN.getException();
|
||||
}
|
||||
SessionManager sessionManager = ApiContext.getSessionManager();
|
||||
// 生成一个新session
|
||||
HttpSession session = sessionManager.getSession(null);
|
||||
WebContext.getInstance().setLoginUser(session, user);
|
||||
return session.getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Api(name = "admin.userinfo.get")
|
||||
@ApiDocMethod(description = "获取用户信息")
|
||||
AdminUserInfoVO getAdminUserInfo() {
|
||||
AdminUserInfo loginUser = WebContext.getInstance().getLoginUser();
|
||||
AdminUserInfoVO adminUserInfoVO = new AdminUserInfoVO();
|
||||
BeanUtils.copyProperties(loginUser, adminUserInfoVO);
|
||||
return adminUserInfoVO;
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system.param;
|
||||
|
||||
import com.gitee.fastmybatis.core.query.param.PageParam;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class IspPageParam extends PageParam {
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:isp_resource
|
||||
* 备注:ISP资源表
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IspResourceParam {
|
||||
|
||||
private Long id;
|
||||
|
||||
/** 资源名称, 数据库字段:name */
|
||||
private String name;
|
||||
|
||||
private String version;
|
||||
|
||||
/** 资源内容(URL), 数据库字段:content */
|
||||
private String content;
|
||||
|
||||
private String extContent;
|
||||
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system.param;
|
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class LoginForm {
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
@ApiDocField(description = "用户名", required = true)
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "密码不能为空")
|
||||
@ApiDocField(description = "密码", required = true)
|
||||
private String password;
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class AdminUserInfoVO {
|
||||
/**
|
||||
* 数据库字段:id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名, 数据库字段:username
|
||||
*/
|
||||
private String username;
|
||||
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
package com.gitee.sop.adminserver.api.system.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 表名:isp_resource
|
||||
* 备注:ISP资源表
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IspResourceResult {
|
||||
|
||||
private Long id;
|
||||
|
||||
/** 资源名称, 数据库字段:name */
|
||||
private String name;
|
||||
|
||||
private String version;
|
||||
|
||||
/** 资源内容(URL), 数据库字段:content */
|
||||
private String content;
|
||||
|
||||
private String extContent;
|
||||
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import com.gitee.sop.adminserver.common.ChannelOperation;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ChannelMsg {
|
||||
|
||||
private static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss:SSS";
|
||||
|
||||
public ChannelMsg(ChannelOperation channelOperation, Object data) {
|
||||
this.operation = channelOperation.getOperation();
|
||||
this.data = data;
|
||||
this.timestamp = DateFormatUtils.format(new Date(), TIME_PATTERN);
|
||||
}
|
||||
|
||||
private String operation;
|
||||
private Object data;
|
||||
|
||||
/**
|
||||
* 加个时间戳,格式yyyy-MM-dd HH:mm:ss:SSS,确保每次推送内容都不一样
|
||||
* nacos监听基于MD5值,如果每次推送的内容一样,则监听不会触发,因此必须确保每次推送的MD5不一样
|
||||
*/
|
||||
private String timestamp;
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class ConfigLimitDto {
|
||||
/** 数据库字段:id */
|
||||
private Long id;
|
||||
|
||||
/** 路由id, 数据库字段:route_id */
|
||||
private String routeId;
|
||||
|
||||
/** 数据库字段:app_key */
|
||||
private String appKey;
|
||||
|
||||
/** 限流ip,多个用英文逗号隔开, 数据库字段:limit_ip */
|
||||
private String limitIp;
|
||||
|
||||
/** 服务id, 数据库字段:service_id */
|
||||
private String serviceId;
|
||||
|
||||
/** 限流策略,1:窗口策略,2:令牌桶策略, 数据库字段:limit_type */
|
||||
private Byte limitType;
|
||||
|
||||
/** 每秒可处理请求数, 数据库字段:exec_count_per_second */
|
||||
private Integer execCountPerSecond;
|
||||
|
||||
/** 限流持续时间,默认1秒,即每durationSeconds秒允许多少请求(当limit_type=1时有效), 数据库字段:durationSeconds */
|
||||
private Integer durationSeconds;
|
||||
|
||||
/** 返回的错误码, 数据库字段:limit_code */
|
||||
private String limitCode;
|
||||
|
||||
/** 返回的错误信息, 数据库字段:limit_msg */
|
||||
private String limitMsg;
|
||||
|
||||
/** 令牌桶容量, 数据库字段:token_bucket_count */
|
||||
private Integer tokenBucketCount;
|
||||
|
||||
/** 限流开启状态,1:开启,0关闭, 数据库字段:limit_status */
|
||||
private Byte limitStatus;
|
||||
|
||||
/** 顺序,值小的优先执行, 数据库字段:order_index */
|
||||
private Integer orderIndex;
|
||||
|
||||
/** 数据库字段:gmt_create */
|
||||
private Date gmtCreate;
|
||||
|
||||
/** 数据库字段:gmt_modified */
|
||||
private Date gmtModified;
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class GatewayFilterDefinition {
|
||||
/** Filter Name */
|
||||
private String name;
|
||||
/** 对应的路由规则 */
|
||||
private Map<String, String> args = new LinkedHashMap<>();
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.validation.ValidationException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class GatewayPredicateDefinition {
|
||||
public static final String GEN_KEY = "_genkey_";
|
||||
/** 断言对应的Name */
|
||||
private String name;
|
||||
/** 配置的断言规则 */
|
||||
private Map<String, String> args = new LinkedHashMap<>();
|
||||
|
||||
public GatewayPredicateDefinition() {
|
||||
}
|
||||
|
||||
public GatewayPredicateDefinition(String text) {
|
||||
int eqIdx = text.indexOf(61);
|
||||
if (eqIdx <= 0) {
|
||||
throw new ValidationException("Unable to parse GatewayPredicateDefinition text '" + text + "', must be of the form name=value");
|
||||
} else {
|
||||
this.setName(text.substring(0, eqIdx));
|
||||
String[] args = StringUtils.tokenizeToStringArray(text.substring(eqIdx + 1), ",");
|
||||
|
||||
for(int i = 0; i < args.length; ++i) {
|
||||
this.args.put(generateName(i), args[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String generateName(int i) {
|
||||
return GEN_KEY + i;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class GatewayPushDTO {
|
||||
private String dataId;
|
||||
private String groupId;
|
||||
private ChannelMsg channelMsg;
|
||||
|
||||
public GatewayPushDTO() {
|
||||
}
|
||||
|
||||
public GatewayPushDTO(String dataId, String groupId, ChannelMsg channelMsg) {
|
||||
this.dataId = dataId;
|
||||
this.groupId = groupId;
|
||||
this.channelMsg = channelMsg;
|
||||
}
|
||||
}
|
@@ -1,437 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.CookieJar;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* http请求工具,基于OKHTTP3
|
||||
* @author 六如
|
||||
*/
|
||||
public class HttpTool {
|
||||
private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
private Map<String, List<Cookie>> cookieStore = new HashMap<String, List<Cookie>>();
|
||||
|
||||
private OkHttpClient httpClient;
|
||||
|
||||
public HttpTool() {
|
||||
this(new HttpToolConfig());
|
||||
}
|
||||
|
||||
public HttpTool(HttpToolConfig httpToolConfig) {
|
||||
this.initHttpClient(httpToolConfig);
|
||||
}
|
||||
|
||||
protected void initHttpClient(HttpToolConfig httpToolConfig) {
|
||||
httpClient = new OkHttpClient.Builder()
|
||||
// 设置链接超时时间,默认10秒
|
||||
.connectTimeout(httpToolConfig.connectTimeoutSeconds, TimeUnit.SECONDS)
|
||||
.readTimeout(httpToolConfig.readTimeoutSeconds, TimeUnit.SECONDS)
|
||||
.writeTimeout(httpToolConfig.writeTimeoutSeconds, TimeUnit.SECONDS)
|
||||
.cookieJar(new CookieJar() {
|
||||
@Override
|
||||
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
|
||||
cookieStore.put(httpUrl.host(), list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
|
||||
List<Cookie> cookies = cookieStore.get(httpUrl.host());
|
||||
return cookies != null ? cookies : new ArrayList<Cookie>();
|
||||
}
|
||||
}).build();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class HttpToolConfig {
|
||||
/**
|
||||
* 请求超时时间
|
||||
*/
|
||||
private int connectTimeoutSeconds = 10;
|
||||
/**
|
||||
* http读取超时时间
|
||||
*/
|
||||
private int readTimeoutSeconds = 10;
|
||||
/**
|
||||
* http写超时时间
|
||||
*/
|
||||
private int writeTimeoutSeconds = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* get请求
|
||||
*
|
||||
* @param url
|
||||
* @param header
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public String get(String url, Map<String, String> header) throws IOException {
|
||||
Request.Builder builder = new Request.Builder().url(url).get();
|
||||
// 添加header
|
||||
addHeader(builder, header);
|
||||
|
||||
Request request = builder.build();
|
||||
Response response = httpClient.newCall(request).execute();
|
||||
return response.body().string();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*
|
||||
* @param url url
|
||||
* @param form 参数
|
||||
* @param header header
|
||||
* @param method 请求方式,post,get等
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public String request(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||
// 添加header
|
||||
addHeader(requestBuilder, header);
|
||||
|
||||
Request request = requestBuilder.build();
|
||||
Response response = httpClient
|
||||
.newCall(request)
|
||||
.execute();
|
||||
try {
|
||||
return response.body().string();
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求json数据,contentType=application/json
|
||||
* @param url 请求路径
|
||||
* @param json json数据
|
||||
* @param header header
|
||||
* @return 返回响应结果
|
||||
* @throws IOException
|
||||
*/
|
||||
public String requestJson(String url, String json, Map<String, String> header) throws IOException {
|
||||
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
|
||||
Request.Builder requestBuilder = new Request.Builder()
|
||||
.url(url)
|
||||
.post(body);
|
||||
// 添加header
|
||||
addHeader(requestBuilder, header);
|
||||
|
||||
Request request = requestBuilder.build();
|
||||
Response response = httpClient
|
||||
.newCall(request)
|
||||
.execute();
|
||||
try {
|
||||
return response.body().string();
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static Request.Builder buildRequestBuilder(String url, Map<String, ?> form, HTTPMethod method) {
|
||||
switch (method) {
|
||||
case GET:
|
||||
return new Request.Builder()
|
||||
.url(buildHttpUrl(url, form))
|
||||
.get();
|
||||
case HEAD:
|
||||
return new Request.Builder()
|
||||
.url(buildHttpUrl(url, form))
|
||||
.head();
|
||||
case PUT:
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.put(buildFormBody(form));
|
||||
case DELETE:
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.delete(buildFormBody(form));
|
||||
default:
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.post(buildFormBody(form));
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpUrl buildHttpUrl(String url, Map<String, ?> form) {
|
||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
|
||||
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||
urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
return urlBuilder.build();
|
||||
}
|
||||
|
||||
public static FormBody buildFormBody(Map<String, ?> form) {
|
||||
FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
||||
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||
paramBuilder.add(entry.getKey(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
return paramBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交表单,并且上传文件
|
||||
*
|
||||
* @param url
|
||||
* @param form
|
||||
* @param header
|
||||
* @param files
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public String requestFile(String url, Map<String, ?> form, Map<String, String> header, List<UploadFile> files)
|
||||
throws IOException {
|
||||
// 创建MultipartBody.Builder,用于添加请求的数据
|
||||
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
|
||||
bodyBuilder.setType(MultipartBody.FORM);
|
||||
|
||||
for (UploadFile uploadFile : files) {
|
||||
// 请求的名字
|
||||
bodyBuilder.addFormDataPart(uploadFile.getName(),
|
||||
// 文件的文字,服务器端用来解析的
|
||||
uploadFile.getFileName(),
|
||||
// 创建RequestBody,把上传的文件放入
|
||||
RequestBody.create(null, uploadFile.getFileData())
|
||||
);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||
bodyBuilder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
|
||||
RequestBody requestBody = bodyBuilder.build();
|
||||
|
||||
Request.Builder builder = new Request.Builder().url(url).post(requestBody);
|
||||
|
||||
// 添加header
|
||||
addHeader(builder, header);
|
||||
|
||||
Request request = builder.build();
|
||||
Response response = httpClient.newCall(request).execute();
|
||||
try {
|
||||
return response.body().string();
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求数据
|
||||
*
|
||||
* @param url 请求url
|
||||
* @param form 请求数据
|
||||
* @param header header
|
||||
* @return 返回Response
|
||||
* @throws IOException
|
||||
*/
|
||||
public Response requestForResponse(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||
// 添加header
|
||||
addHeader(requestBuilder, header);
|
||||
|
||||
Request request = requestBuilder.build();
|
||||
return httpClient
|
||||
.newCall(request)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param url 请求url
|
||||
* @param form 请求数据
|
||||
* @param header header
|
||||
* @return 返回文件流
|
||||
* @throws IOException
|
||||
*/
|
||||
public InputStream downloadFile(String url, Map<String, ?> form, Map<String, String> header) throws IOException {
|
||||
Request.Builder requestBuilder = buildRequestBuilder(url, form, HTTPMethod.GET);
|
||||
// 添加header
|
||||
addHeader(requestBuilder, header);
|
||||
|
||||
Request request = requestBuilder.build();
|
||||
Response response = httpClient
|
||||
.newCall(request)
|
||||
.execute();
|
||||
if (response.isSuccessful()) {
|
||||
ResponseBody body = response.body();
|
||||
return body == null ? null : body.byteStream();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addHeader(Request.Builder builder, Map<String, String> header) {
|
||||
if (header != null) {
|
||||
Set<Map.Entry<String, String>> entrySet = header.entrySet();
|
||||
for (Map.Entry<String, String> entry : entrySet) {
|
||||
builder.addHeader(entry.getKey(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCookieStore(Map<String, List<Cookie>> cookieStore) {
|
||||
this.cookieStore = cookieStore;
|
||||
}
|
||||
|
||||
public void setHttpClient(OkHttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public enum HTTPMethod {
|
||||
/** http GET */
|
||||
GET,
|
||||
/** http POST */
|
||||
POST,
|
||||
/** http PUT */
|
||||
PUT,
|
||||
/** http HEAD */
|
||||
HEAD,
|
||||
/** http DELETE */
|
||||
DELETE;
|
||||
|
||||
private HTTPMethod() {
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
public static HTTPMethod fromValue(String v) {
|
||||
return valueOf(v.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传类
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public static class UploadFile implements Serializable {
|
||||
private static final long serialVersionUID = -1100614660944996398L;
|
||||
|
||||
/**
|
||||
* @param name 表单名称,不能重复
|
||||
* @param file 文件
|
||||
* @throws IOException
|
||||
*/
|
||||
public UploadFile(String name, File file) throws IOException {
|
||||
this(name, file.getName(), FileUtil.toBytes(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 表单名称,不能重复
|
||||
* @param fileName 文件名
|
||||
* @param input 文件流
|
||||
* @throws IOException
|
||||
*/
|
||||
public UploadFile(String name, String fileName, InputStream input) throws IOException {
|
||||
this(name, fileName, FileUtil.toBytes(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name 表单名称,不能重复
|
||||
* @param fileName 文件名
|
||||
* @param fileData 文件数据
|
||||
*/
|
||||
public UploadFile(String name, String fileName, byte[] fileData) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.fileName = fileName;
|
||||
this.fileData = fileData;
|
||||
this.md5 = DigestUtils.md5Hex(fileData);
|
||||
}
|
||||
|
||||
private String name;
|
||||
private String fileName;
|
||||
private byte[] fileData;
|
||||
private String md5;
|
||||
|
||||
}
|
||||
|
||||
public static class FileUtil {
|
||||
|
||||
/**
|
||||
* The default buffer size to use.
|
||||
*/
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
||||
private static final int EOF = -1;
|
||||
|
||||
/**
|
||||
* 将文件流转换成byte[]
|
||||
* @param input
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] toBytes(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
int n = 0;
|
||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||
|
||||
while (EOF != (n = input.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件转换成数据流
|
||||
* @param file 文件
|
||||
* @return 返回数据流
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] toBytes(File file) throws IOException {
|
||||
if (file.exists()) {
|
||||
if (file.isDirectory()) {
|
||||
throw new IOException("File '" + file + "' exists but is a directory");
|
||||
}
|
||||
if (file.canRead() == false) {
|
||||
throw new IOException("File '" + file + "' cannot be read");
|
||||
}
|
||||
} else {
|
||||
throw new FileNotFoundException("File '" + file + "' does not exist");
|
||||
}
|
||||
InputStream input = null;
|
||||
try {
|
||||
input = new FileInputStream(file);
|
||||
return toBytes(input);
|
||||
} finally {
|
||||
try {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* isv授权过的路由
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class IsvRoutePermission {
|
||||
private String appKey;
|
||||
private List<String> routeIdList;
|
||||
private String routeIdListMd5;
|
||||
private String listenPath;
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public enum MetadataEnum {
|
||||
/**
|
||||
* 预发布环境
|
||||
*/
|
||||
ENV_PRE("env", "pre"),
|
||||
|
||||
/**
|
||||
* 上线环境
|
||||
*/
|
||||
ENV_ONLINE("env", ""),
|
||||
|
||||
/**
|
||||
* 灰度环境
|
||||
*/
|
||||
ENV_GRAY("env", "gray"),
|
||||
;
|
||||
private String key,value;
|
||||
|
||||
MetadataEnum(String key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class NacosConfigs {
|
||||
|
||||
public static final String GROUP_CHANNEL = "sop:channel";
|
||||
|
||||
public static final String GROUP_ROUTE = "sop:route";
|
||||
|
||||
public static final String DATA_ID_GRAY = "com.gitee.sop.channel.gray";
|
||||
|
||||
public static final String DATA_ID_IP_BLACKLIST = "com.gitee.sop.channel.ipblacklist";
|
||||
|
||||
public static final String DATA_ID_ISV = "com.gitee.sop.channel.isv";
|
||||
|
||||
public static final String DATA_ID_ROUTE_PERMISSION = "com.gitee.sop.channel.routepermission";
|
||||
|
||||
public static final String DATA_ID_LIMIT_CONFIG = "com.gitee.sop.channel.limitconfig";
|
||||
|
||||
public static final String DATA_ID_ROUTE_CONFIG = "com.gitee.sop.channel.routeconfig";
|
||||
|
||||
private static final String DATA_ID_TPL = "com.gitee.sop.route.%s";
|
||||
|
||||
public static String getRouteDataId(String serviceId) {
|
||||
return String.format(DATA_ID_TPL, serviceId);
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RouteConfigDto {
|
||||
|
||||
/**
|
||||
* 路由id
|
||||
*/
|
||||
private String routeId;
|
||||
|
||||
/**
|
||||
* 状态,0:待审核,1:启用,2:禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class RouteErrorCount {
|
||||
|
||||
private String routeId;
|
||||
private Integer count;
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceGrayDefinition {
|
||||
private String serviceId;
|
||||
private String instanceId;
|
||||
private String data;
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class ServiceInfo {
|
||||
/** 服务名称 */
|
||||
private String serviceId;
|
||||
/** 实例列表 */
|
||||
private List<ServiceInstance> instances;
|
||||
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public void setServiceId(String serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
public List<ServiceInstance> getInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
public void setInstances(List<ServiceInstance> instances) {
|
||||
this.instances = instances;
|
||||
}
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
package com.gitee.sop.adminserver.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Data
|
||||
public class ServiceInstance {
|
||||
/**
|
||||
* 实例id
|
||||
*/
|
||||
private String instanceId;
|
||||
|
||||
/**
|
||||
* 服务名称
|
||||
*/
|
||||
private String serviceId;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* port
|
||||
*/
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* 服务状态,UP:已上线,OUT_OF_SERVICE:已下线
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private String updateTime;
|
||||
|
||||
/**
|
||||
* user extended attributes
|
||||
*/
|
||||
private Map<String, String> metadata = new HashMap<String, String>();
|
||||
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import com.gitee.easyopen.message.ErrorMeta;
|
||||
|
||||
/**
|
||||
* 定义错误的地方
|
||||
* @author 六如
|
||||
*/
|
||||
public class AdminErrors {
|
||||
private AdminErrors(){}
|
||||
|
||||
/** error_zh_CN2.properties内容前缀 */
|
||||
static String isvModule = "isv.error_";
|
||||
|
||||
|
||||
public static final ErrorMeta NO_LOGIN = new ErrorMeta(isvModule, "-100", "用户未登录");
|
||||
|
||||
public static final ErrorMeta ERROR_USERNAME_PWD = new ErrorMeta(isvModule, "1", "用户名密码错误");
|
||||
public static final ErrorMeta DUPLICATE_USERNAME = new ErrorMeta(isvModule, "2", "该用户名已被注册");
|
||||
|
||||
public static final ErrorMeta NO_RECORD = new ErrorMeta(isvModule, "1000", "无操作记录");
|
||||
public static final ErrorMeta ERROR_VALIDATE = new ErrorMeta(isvModule, "1001", "验证失败");
|
||||
public static final ErrorMeta NULL_OBJECT = new ErrorMeta(isvModule, "1002", "null对象");
|
||||
public static final ErrorMeta ERROR_SERACH = new ErrorMeta(isvModule, "1004", "查询错误");
|
||||
public static final ErrorMeta ERROR_EXPORT = new ErrorMeta(isvModule, "1005", "导出错误");
|
||||
public static final ErrorMeta CLASS_NEW_ERROR = new ErrorMeta(isvModule, "1007", "系统错误");
|
||||
|
||||
public static final ErrorMeta ERROR_SAVE = new ErrorMeta(isvModule, "10010", "保存失败");
|
||||
public static final ErrorMeta ERROR_UPDATE = new ErrorMeta(isvModule, "10011", "修改失败");
|
||||
public static final ErrorMeta DELETE_UPDATE = new ErrorMeta(isvModule, "10012", "删除失败");
|
||||
public static final ErrorMeta RECORD_EXSIT = new ErrorMeta(isvModule, "10013", "记录已存在");
|
||||
public static final ErrorMeta ERROR_OPT = new ErrorMeta(isvModule, "10014", "非法操作");
|
||||
|
||||
public static final ErrorMeta NO_USER = new ErrorMeta(isvModule, "10015", "用户不存在");
|
||||
|
||||
public static final ErrorMeta USER_FORBIDDEN = new ErrorMeta(isvModule, "10016", "用户已禁用");
|
||||
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import com.gitee.easyopen.exception.ApiException;
|
||||
import com.gitee.easyopen.message.Error;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class BizException extends ApiException {
|
||||
public BizException(String msg) {
|
||||
super(msg, "4000");
|
||||
}
|
||||
|
||||
public BizException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public BizException(Error<String> error) {
|
||||
super(error);
|
||||
}
|
||||
|
||||
public BizException(String msg, String code) {
|
||||
super(msg, code);
|
||||
}
|
||||
|
||||
public BizException(String msg, String code, Object data) {
|
||||
super(msg, code, data);
|
||||
}
|
||||
|
||||
public BizException(Error<String> error, Object data) {
|
||||
super(error, data);
|
||||
}
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public enum ChannelOperation {
|
||||
/**
|
||||
* 限流推送路由配置-修改
|
||||
*/
|
||||
LIMIT_CONFIG_UPDATE("update"),
|
||||
|
||||
/**
|
||||
* 路由信息更新
|
||||
*/
|
||||
ROUTE_CONFIG_UPDATE("update"),
|
||||
|
||||
/**
|
||||
* isv信息修改
|
||||
*/
|
||||
ISV_INFO_UPDATE("update"),
|
||||
|
||||
/**
|
||||
* 黑名单消息类型:添加
|
||||
*/
|
||||
BLACKLIST_ADD("add"),
|
||||
/**
|
||||
* 黑名单消息类型:删除
|
||||
*/
|
||||
BLACKLIST_DELETE("delete"),
|
||||
|
||||
/**
|
||||
* 路由权限配置更新
|
||||
*/
|
||||
ROUTE_PERMISSION_UPDATE("update"),
|
||||
/**
|
||||
* 路由权限加载
|
||||
*/
|
||||
ROUTE_PERMISSION_RELOAD("reload"),
|
||||
|
||||
/**
|
||||
* 灰度发布设置
|
||||
*/
|
||||
GRAY_USER_KEY_SET("set"),
|
||||
/**
|
||||
* 灰度发布-开启
|
||||
*/
|
||||
GRAY_USER_KEY_OPEN("open"),
|
||||
/**
|
||||
* 灰度发布-关闭
|
||||
*/
|
||||
GRAY_USER_KEY_CLOSE("close"),
|
||||
|
||||
;
|
||||
|
||||
private String operation;
|
||||
|
||||
ChannelOperation(String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
@Slf4j
|
||||
public class CopyUtil {
|
||||
|
||||
public static void copyProperties(Object from, Object to) {
|
||||
BeanUtils.copyProperties(from, to);
|
||||
}
|
||||
|
||||
public static <T> T copyBean(Object from, Supplier<T> supplier) {
|
||||
Objects.requireNonNull(from);
|
||||
T to = supplier.get();
|
||||
BeanUtils.copyProperties(from, to);
|
||||
return to;
|
||||
}
|
||||
|
||||
public static <T> T copyBeanNullable(Object from, Supplier<T> supplier) {
|
||||
if (from == null) {
|
||||
return supplier.get();
|
||||
}
|
||||
T to = supplier.get();
|
||||
BeanUtils.copyProperties(from, to);
|
||||
return to;
|
||||
}
|
||||
|
||||
public static <T> T copyBean(Object from, Supplier<T> supplier, Consumer<T> after) {
|
||||
if (from == null) {
|
||||
return null;
|
||||
}
|
||||
T to = supplier.get();
|
||||
BeanUtils.copyProperties(from, to);
|
||||
after.accept(to);
|
||||
return to;
|
||||
}
|
||||
|
||||
public static <T> List<T> copyList(List<?> fromList, Supplier<T> toElement) {
|
||||
if (fromList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return fromList.stream()
|
||||
.map(source -> {
|
||||
T target = toElement.get();
|
||||
BeanUtils.copyProperties(source, target);
|
||||
return target;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T> List<T> copyList(List<?> fromList, Supplier<T> toElement, Consumer<T> after) {
|
||||
if (fromList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return fromList.stream()
|
||||
.map(source -> {
|
||||
T target = toElement.get();
|
||||
BeanUtils.copyProperties(source, target);
|
||||
after.accept(target);
|
||||
return target;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -1,167 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class IdGen {
|
||||
private static long workId = 0;
|
||||
private static SnowflakeIdWorker worker = new SnowflakeIdWorker(workId++, 0);
|
||||
|
||||
/**
|
||||
* 生成唯一id
|
||||
* @return
|
||||
*/
|
||||
public static String nextId() {
|
||||
return String.valueOf(worker.nextId());
|
||||
}
|
||||
|
||||
public static String uuid() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Twitter_Snowflake<br>
|
||||
* SnowFlake的结构如下(每部分用-分开):<br>
|
||||
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
|
||||
* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
|
||||
* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
|
||||
* 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
|
||||
* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
|
||||
* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
|
||||
* 加起来刚好64位,为一个Long型。<br>
|
||||
* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
|
||||
*/
|
||||
public static class SnowflakeIdWorker {
|
||||
|
||||
// ==============================Fields===========================================
|
||||
/** 开始时间截 (2015-01-01) */
|
||||
private final long twepoch = 1420041100000L;
|
||||
|
||||
/** 机器id所占的位数 */
|
||||
private final long workerIdBits = 5L;
|
||||
|
||||
/** 数据标识id所占的位数 */
|
||||
private final long datacenterIdBits = 5L;
|
||||
|
||||
/** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
|
||||
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
|
||||
/** 支持的最大数据标识id,结果是31 */
|
||||
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
||||
|
||||
/** 序列在id中占的位数 */
|
||||
private final long sequenceBits = 12L;
|
||||
|
||||
/** 机器ID向左移12位 */
|
||||
private final long workerIdShift = sequenceBits;
|
||||
|
||||
/** 数据标识id向左移17位(12+5) */
|
||||
private final long datacenterIdShift = sequenceBits + workerIdBits;
|
||||
|
||||
/** 时间截向左移22位(5+5+12) */
|
||||
private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
||||
|
||||
/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
|
||||
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
|
||||
/** 工作机器ID(0~31) */
|
||||
private long workerId;
|
||||
|
||||
/** 数据中心ID(0~31) */
|
||||
private long datacenterId;
|
||||
|
||||
/** 毫秒内序列(0~4095) */
|
||||
private long sequence = 0L;
|
||||
|
||||
/** 上次生成ID的时间截 */
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
//==============================Constructors=====================================
|
||||
/**
|
||||
* 构造函数
|
||||
* @param workerId 工作ID (0~31)
|
||||
* @param datacenterId 数据中心ID (0~31)
|
||||
*/
|
||||
public SnowflakeIdWorker(long workerId, long datacenterId) {
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
||||
}
|
||||
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
||||
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
||||
}
|
||||
this.workerId = workerId;
|
||||
this.datacenterId = datacenterId;
|
||||
}
|
||||
|
||||
// ==============================Methods==========================================
|
||||
/**
|
||||
* 获得下一个ID (该方法是线程安全的)
|
||||
* @return SnowflakeId
|
||||
*/
|
||||
public synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
|
||||
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(
|
||||
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
//如果是同一时间生成的,则进行毫秒内序列
|
||||
if (lastTimestamp == timestamp) {
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
//毫秒内序列溢出
|
||||
if (sequence == 0) {
|
||||
//阻塞到下一个毫秒,获得新的时间戳
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
}
|
||||
//时间戳改变,毫秒内序列重置
|
||||
else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
//上次生成ID的时间截
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
//移位并通过或运算拼到一起组成64位的ID
|
||||
return ((timestamp - twepoch) << timestampLeftShift)
|
||||
| (datacenterId << datacenterIdShift)
|
||||
| (workerId << workerIdShift)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* 阻塞到下一个毫秒,直到获得新的时间戳
|
||||
* @param lastTimestamp 上次生成ID的时间截
|
||||
* @return 当前时间戳
|
||||
*/
|
||||
protected long tilNextMillis(long lastTimestamp) {
|
||||
long timestamp = timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以毫秒为单位的当前时间
|
||||
* @return 当前时间(毫秒)
|
||||
*/
|
||||
protected long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
/*//==============================Test=============================================
|
||||
*/
|
||||
/** 测试
|
||||
public static void main(String[] args) {
|
||||
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
long id = idWorker.nextId();
|
||||
System.out.println("id:" + id);
|
||||
System.out.println("toBinaryString:" + Long.toBinaryString(id));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
/**
|
||||
* 限流
|
||||
* @author 六如
|
||||
*/
|
||||
public enum LimitEnum {
|
||||
/**
|
||||
* 限流策略,1:窗口策略
|
||||
*/
|
||||
TYPE_LEAKY_BUCKET((byte) 1),
|
||||
/**
|
||||
* 限流策略,2:令牌桶策略
|
||||
*/
|
||||
TYPE_TOKEN_BUCKET((byte) 2),
|
||||
/**
|
||||
* 1:开启
|
||||
*/
|
||||
STATUS_OPEN((byte) 1),
|
||||
/**
|
||||
* 0关闭
|
||||
*/
|
||||
STATUS_CLOSE((byte) 0),
|
||||
|
||||
;
|
||||
|
||||
LimitEnum(byte val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
private byte val;
|
||||
|
||||
public byte getVal() {
|
||||
return val;
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import com.gitee.easyopen.verify.DefaultMd5Verifier;
|
||||
import com.gitee.sop.adminserver.bean.HttpTool;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 六如
|
||||
*/
|
||||
public class QueryUtil {
|
||||
|
||||
private static HttpTool httpTool = new HttpTool();
|
||||
|
||||
public static String buildQueryString(Map<String, ?> params) throws UnsupportedEncodingException {
|
||||
if (params == null || params.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder query = new StringBuilder();
|
||||
int i = 0;
|
||||
for (Map.Entry<String, ?> entry : params.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String value = String.valueOf(entry.getValue());
|
||||
if (i++ > 0) {
|
||||
query.append("&");
|
||||
}
|
||||
query.append(name).append("=").append(URLEncoder.encode(value, "UTF-8"));
|
||||
}
|
||||
return query.toString();
|
||||
}
|
||||
|
||||
public static String requestServer(String ipPort, String path, String secret) throws Exception {
|
||||
DefaultMd5Verifier md5Verifier = new DefaultMd5Verifier();
|
||||
Map<String, Object> params = new HashMap<>(16);
|
||||
params.put("time", System.currentTimeMillis());
|
||||
String sign = md5Verifier.buildSign(params, secret);
|
||||
params.put("sign", sign);
|
||||
String query = QueryUtil.buildQueryString(params);
|
||||
path = path.startsWith("/") ? path.substring(1) : path;
|
||||
String url = "http://" + ipPort + "/" + path + "?" + query;
|
||||
return httpTool.get(url, null);
|
||||
}
|
||||
}
|
@@ -1,417 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.bouncycastle.asn1.ASN1Encodable;
|
||||
import org.bouncycastle.asn1.ASN1Primitive;
|
||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* RSA加解密工具<br>
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
public class RSATool {
|
||||
public static String RSA_ALGORITHM = "RSA";
|
||||
|
||||
private KeyFormat keyFormat;
|
||||
private KeyLength keyLength;
|
||||
|
||||
public RSATool(KeyFormat keyFormat, KeyLength keyLength) {
|
||||
this.keyFormat = keyFormat;
|
||||
this.keyLength = keyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建公钥私钥
|
||||
*
|
||||
* @return 返回公私钥对
|
||||
* @throws Exception
|
||||
*/
|
||||
public KeyStore createKeys() throws Exception {
|
||||
KeyPairGenerator keyPairGeno = KeyPairGenerator.getInstance(RSA_ALGORITHM);
|
||||
keyPairGeno.initialize(keyLength.getLength());
|
||||
KeyPair keyPair = keyPairGeno.generateKeyPair();
|
||||
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
|
||||
KeyStore keyStore = new KeyStore();
|
||||
if (this.keyFormat == KeyFormat.PKCS1) {
|
||||
keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded()));
|
||||
keyStore.setPrivateKey(convertPkcs8ToPkcs1(privateKey.getEncoded()));
|
||||
} else {
|
||||
keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded()));
|
||||
keyStore.setPrivateKey(Base64.encodeBase64String(privateKey.getEncoded()));
|
||||
}
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公钥对象
|
||||
*
|
||||
* @param pubKeyData 公钥
|
||||
* @return 返回公钥对象
|
||||
* @throws Exception
|
||||
*/
|
||||
public RSAPublicKey getPublicKey(byte[] pubKeyData) throws Exception {
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKeyData);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公钥对象
|
||||
*
|
||||
* @param pubKey 公钥
|
||||
* @return 返回私钥对象
|
||||
* @throws Exception
|
||||
*/
|
||||
public RSAPublicKey getPublicKey(String pubKey) throws Exception {
|
||||
return getPublicKey(Base64.decodeBase64(pubKey));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取私钥对象
|
||||
*
|
||||
* @param priKey 私钥
|
||||
* @return 私钥对象
|
||||
* @throws Exception
|
||||
*/
|
||||
public RSAPrivateKey getPrivateKey(String priKey) throws Exception {
|
||||
return getPrivateKey(Base64.decodeBase64(priKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过私钥byte[]将公钥还原,适用于RSA算法
|
||||
*
|
||||
* @param keyBytes
|
||||
* @return 返回私钥
|
||||
* @throws Exception
|
||||
*/
|
||||
public RSAPrivateKey getPrivateKey(byte[] keyBytes) throws Exception {
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param data 待加密内容
|
||||
* @param publicKey 公钥
|
||||
* @return 返回密文
|
||||
* @throws Exception
|
||||
*/
|
||||
public String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
// 模长
|
||||
int key_len = publicKey.getModulus().bitLength() / 8;
|
||||
// 加密数据长度 <= 模长-11
|
||||
String[] datas = splitString(data, key_len - 11);
|
||||
String mi = "";
|
||||
// 如果明文长度大于模长-11则要分组加密
|
||||
for (String s : datas) {
|
||||
mi += bcd2Str(cipher.doFinal(s.getBytes()));
|
||||
}
|
||||
return mi;
|
||||
}
|
||||
|
||||
public String encryptByPrivateKey(String data, String privateKey) throws Exception {
|
||||
return encryptByPrivateKey(data, getPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param data 待加密数据
|
||||
* @param privateKey 私钥
|
||||
* @return 返回密文
|
||||
* @throws Exception
|
||||
*/
|
||||
public String encryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
// 模长
|
||||
int key_len = privateKey.getModulus().bitLength() / 8;
|
||||
// 加密数据长度 <= 模长-11
|
||||
String[] datas = splitString(data, key_len - 11);
|
||||
String mi = "";
|
||||
// 如果明文长度大于模长-11则要分组加密
|
||||
for (String s : datas) {
|
||||
mi += bcd2Str(cipher.doFinal(s.getBytes()));
|
||||
}
|
||||
return mi;
|
||||
}
|
||||
|
||||
public String decryptByPrivateKey(String data, String privateKey) throws Exception {
|
||||
return decryptByPrivateKey(data, getPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param data 待解密内容
|
||||
* @param privateKey 私钥
|
||||
* @return 返回明文
|
||||
* @throws Exception
|
||||
*/
|
||||
public String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
// 模长
|
||||
int key_len = privateKey.getModulus().bitLength() / 8;
|
||||
byte[] bytes = data.getBytes();
|
||||
byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
|
||||
// 如果密文长度大于模长则要分组解密
|
||||
String ming = "";
|
||||
byte[][] arrays = splitArray(bcd, key_len);
|
||||
for (byte[] arr : arrays) {
|
||||
ming += new String(cipher.doFinal(arr));
|
||||
}
|
||||
return ming;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥解密
|
||||
*
|
||||
* @param data 待解密内容
|
||||
* @param rsaPublicKey 公钥
|
||||
* @return 返回明文
|
||||
* @throws Exception
|
||||
*/
|
||||
public String decryptByPublicKey(String data, RSAPublicKey rsaPublicKey) throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(keyFormat.getCipherAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, rsaPublicKey);
|
||||
// 模长
|
||||
int key_len = rsaPublicKey.getModulus().bitLength() / 8;
|
||||
byte[] bytes = data.getBytes();
|
||||
byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
|
||||
// 如果密文长度大于模长则要分组解密
|
||||
String ming = "";
|
||||
byte[][] arrays = splitArray(bcd, key_len);
|
||||
for (byte[] arr : arrays) {
|
||||
ming += new String(cipher.doFinal(arr));
|
||||
}
|
||||
return ming;
|
||||
}
|
||||
|
||||
public static String convertPkcs8ToPkcs1(byte[] privateKeyData) throws Exception{
|
||||
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privateKeyData);
|
||||
ASN1Encodable encodable = pkInfo.parsePrivateKey();
|
||||
ASN1Primitive primitive = encodable.toASN1Primitive();
|
||||
byte[] privateKeyPKCS1 = primitive.getEncoded();
|
||||
return Base64.encodeBase64String(privateKeyPKCS1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ASCII码转BCD码
|
||||
*/
|
||||
public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {
|
||||
byte[] bcd = new byte[asc_len / 2];
|
||||
int j = 0;
|
||||
for (int i = 0; i < (asc_len + 1) / 2; i++) {
|
||||
bcd[i] = asc_to_bcd(ascii[j++]);
|
||||
bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++]) & 0xff) + (bcd[i] << 4));
|
||||
}
|
||||
return bcd;
|
||||
}
|
||||
|
||||
public static byte asc_to_bcd(byte asc) {
|
||||
byte bcd;
|
||||
|
||||
if ((asc >= '0') && (asc <= '9')) {
|
||||
bcd = (byte) (asc - '0');
|
||||
} else if ((asc >= 'A') && (asc <= 'F')) {
|
||||
bcd = (byte) (asc - 'A' + 10);
|
||||
} else if ((asc >= 'a') && (asc <= 'f')) {
|
||||
bcd = (byte) (asc - 'a' + 10);
|
||||
} else {
|
||||
bcd = (byte) (asc - 48);
|
||||
}
|
||||
return bcd;
|
||||
}
|
||||
|
||||
/**
|
||||
* BCD转字符串
|
||||
*/
|
||||
public String bcd2Str(byte[] bytes) {
|
||||
char[] temp = new char[bytes.length * 2];
|
||||
char val;
|
||||
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
|
||||
temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
|
||||
|
||||
val = (char) (bytes[i] & 0x0f);
|
||||
temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
|
||||
}
|
||||
return new String(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拆分字符串
|
||||
*/
|
||||
public String[] splitString(String string, int len) {
|
||||
int x = string.length() / len;
|
||||
int y = string.length() % len;
|
||||
int z = 0;
|
||||
if (y != 0) {
|
||||
z = 1;
|
||||
}
|
||||
String[] strings = new String[x + z];
|
||||
String str = "";
|
||||
for (int i = 0; i < x + z; i++) {
|
||||
if (i == x + z - 1 && y != 0) {
|
||||
str = string.substring(i * len, i * len + y);
|
||||
} else {
|
||||
str = string.substring(i * len, i * len + len);
|
||||
}
|
||||
strings[i] = str;
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拆分数组
|
||||
*/
|
||||
public byte[][] splitArray(byte[] data, int len) {
|
||||
int x = data.length / len;
|
||||
int y = data.length % len;
|
||||
int z = 0;
|
||||
if (y != 0) {
|
||||
z = 1;
|
||||
}
|
||||
byte[][] arrays = new byte[x + z][];
|
||||
byte[] arr;
|
||||
for (int i = 0; i < x + z; i++) {
|
||||
arr = new byte[len];
|
||||
if (i == x + z - 1 && y != 0) {
|
||||
System.arraycopy(data, i * len, arr, 0, y);
|
||||
} else {
|
||||
System.arraycopy(data, i * len, arr, 0, len);
|
||||
}
|
||||
arrays[i] = arr;
|
||||
}
|
||||
return arrays;
|
||||
}
|
||||
|
||||
public enum KeyLength {
|
||||
/**
|
||||
* 秘钥长度:1024
|
||||
*/
|
||||
LENGTH_1024(1024),
|
||||
/**
|
||||
* 秘钥长度:2048
|
||||
*/
|
||||
LENGTH_2048(2048);
|
||||
private int length;
|
||||
|
||||
KeyLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyStore {
|
||||
private String publicKey;
|
||||
private String privateKey;
|
||||
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void setPublicKey(String publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public void setPrivateKey(String privateKey) {
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
|
||||
public enum KeyFormat {
|
||||
PKCS1("RSA/ECB/PKCS1Padding"), PKCS8("RSA");
|
||||
private String cipherAlgorithm;
|
||||
|
||||
KeyFormat(String cipherAlgorithm) {
|
||||
this.cipherAlgorithm = cipherAlgorithm;
|
||||
}
|
||||
|
||||
public String getCipherAlgorithm() {
|
||||
return cipherAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
public KeyFormat getKeyFormat() {
|
||||
return keyFormat;
|
||||
}
|
||||
|
||||
public KeyLength getKeyLength() {
|
||||
return keyLength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------ Test ------------
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
RSATool rsa_pkcs8_1024 = new RSATool(KeyFormat.PKCS8, KeyLength.LENGTH_1024);
|
||||
RSATool rsa_pkcs8_2048 = new RSATool(KeyFormat.PKCS8, KeyLength.LENGTH_2048);
|
||||
|
||||
doTest(rsa_pkcs8_1024);
|
||||
doTest(rsa_pkcs8_2048);
|
||||
|
||||
// PKCS在Java环境无法测试,可以生成一对,到非java平台测试,如C#
|
||||
}
|
||||
|
||||
private static void doTest(RSATool rsaTool) throws Exception {
|
||||
System.out.println("秘钥格式:" + rsaTool.keyFormat.name() + ", 秘钥长度:" + rsaTool.keyLength.getLength());
|
||||
KeyStore keys = rsaTool.createKeys();
|
||||
String pubKey = keys.getPublicKey();
|
||||
System.out.println("pubKey:");
|
||||
System.out.println(pubKey);
|
||||
String priKey = keys.getPrivateKey();
|
||||
System.out.println("priKey:");
|
||||
System.out.println(priKey);
|
||||
System.out.println("--------");
|
||||
|
||||
String ming = "你好,abc123~!@=";
|
||||
// 用公钥加密
|
||||
String mi = rsaTool.encryptByPublicKey(ming, rsaTool.getPublicKey(pubKey));
|
||||
System.out.println("mi : " + mi);
|
||||
// 用私钥解密
|
||||
String ming2 = rsaTool.decryptByPrivateKey(mi, rsaTool.getPrivateKey(priKey));
|
||||
System.out.println("ming : " + ming2 + ", 结果:" + ming2.equals(ming));
|
||||
|
||||
// 用私钥加密
|
||||
String mi2 = rsaTool.encryptByPrivateKey(ming, rsaTool.getPrivateKey(priKey));
|
||||
|
||||
System.out.println("mi2 : " + mi2);
|
||||
// 用公钥解密
|
||||
String ming3 = rsaTool.decryptByPublicKey(mi2, rsaTool.getPublicKey(pubKey));
|
||||
System.out.println("ming3 : " + ming3 + ", 结果:" + ming3.equals(ming));
|
||||
System.out.println("---------------------");
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
package com.gitee.sop.adminserver.common;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 通用状态枚举
|
||||
*
|
||||
* @author 六如
|
||||
*/
|
||||
@Getter
|
||||
public enum StatusEnum {
|
||||
/**
|
||||
* 启用
|
||||
*/
|
||||
STATUS_ENABLE((byte)1),
|
||||
/**
|
||||
* 禁用
|
||||
*/
|
||||
STATUS_DISABLE((byte)0),
|
||||
;
|
||||
private byte status;
|
||||
|
||||
StatusEnum(byte status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user