commit
51e17486dd
@ -1,28 +1,31 @@ |
||||
* [首页](/?t=1559803778913) |
||||
* [首页](/?t=1562549680042) |
||||
* 开发文档 |
||||
* [快速体验](files/10010_快速体验.md?t=1559803778920) |
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1559803778940) |
||||
* [新增接口](files/10020_新增接口.md?t=1559803778940) |
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1559803778940) |
||||
* [错误处理](files/10040_错误处理.md?t=1559803778940) |
||||
* [编写文档](files/10041_编写文档.md?t=1559803778941) |
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1559803778941) |
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1559803778941) |
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1559803778941) |
||||
* [ISV管理](files/10085_ISV管理.md?t=1559803778941) |
||||
* [路由授权](files/10090_路由授权.md?t=1559803778941) |
||||
* [接口限流](files/10092_接口限流.md?t=1559803778941) |
||||
* [监控日志](files/10093_监控日志.md?t=1559803778941) |
||||
* [SDK开发](files/10095_SDK开发.md?t=1559803778941) |
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1559803778942) |
||||
* [应用授权](files/10097_应用授权.md?t=1559803778942) |
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1559803778942) |
||||
* [对接前端](files/10100_对接前端.md?t=1559803778942) |
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1559803778942) |
||||
* [文件上传](files/10104_文件上传.md?t=1559803778942) |
||||
* [快速体验](files/10010_快速体验.md?t=1562549680042) |
||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1562549680065) |
||||
* [新增接口](files/10020_新增接口.md?t=1562549680065) |
||||
* [业务参数校验](files/10030_业务参数校验.md?t=1562549680065) |
||||
* [错误处理](files/10040_错误处理.md?t=1562549680065) |
||||
* [编写文档](files/10041_编写文档.md?t=1562549680065) |
||||
* [接口交互详解](files/10050_接口交互详解.md?t=1562549680065) |
||||
* [easyopen支持](files/10070_easyopen支持.md?t=1562549680065) |
||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1562549680066) |
||||
* [ISV管理](files/10085_ISV管理.md?t=1562549680066) |
||||
* [自定义路由](files/10086_自定义路由.md?t=1562549680066) |
||||
* [路由授权](files/10090_路由授权.md?t=1562549680066) |
||||
* [接口限流](files/10092_接口限流.md?t=1562549680066) |
||||
* [监控日志](files/10093_监控日志.md?t=1562549680066) |
||||
* [SDK开发](files/10095_SDK开发.md?t=1562549680067) |
||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1562549680067) |
||||
* [应用授权](files/10097_应用授权.md?t=1562549680067) |
||||
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1562549680067) |
||||
* [对接前端](files/10100_对接前端.md?t=1562549680067) |
||||
* [自定义过滤器](files/10102_自定义过滤器.md?t=1562549680067) |
||||
* [文件上传](files/10104_文件上传.md?t=1562549680068) |
||||
* [nacos注册中心](files/10106_nacos注册中心.md?t=1562549680068) |
||||
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1562549680069) |
||||
* 原理分析 |
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1559803778942) |
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1559803778942) |
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1559803778942) |
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1559803778942) |
||||
* [常见问题](files/90100_常见问题.md?t=1559803778942) |
||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1562549680069) |
||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1562549680069) |
||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1562549680069) |
||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1562549680069) |
||||
* [常见问题](files/90100_常见问题.md?t=1562549680069) |
||||
|
@ -0,0 +1,23 @@ |
||||
# 自定义路由 |
||||
|
||||
假设有一个非java开发的接口,比如php开发的接口,然后需要接入到SOP,使用接口名版本号进行路由跳转。 |
||||
|
||||
操作方式如下: |
||||
|
||||
- 登录sop-admin,服务管理--路由管理 |
||||
- 新建一个自定义服务:`php-service` |
||||
|
||||
 |
||||
|
||||
- 选中php-service,新建一个路由,输入接口名、版本号、uri |
||||
|
||||
 |
||||
|
||||
- 请求网关 |
||||
|
||||
`http://localhost:8081/api?method=php.goods.list&version=1.0`会跳转到`http://www.xxx.com/api/listGoods.php` |
||||
|
||||
注意: |
||||
|
||||
- php接口返回数据必须是json格式,返回其它内容可能会调用失败 |
||||
- 只有自定义服务、路由可以删除 |
@ -0,0 +1,90 @@ |
||||
# nacos注册中心 |
||||
|
||||
使用nacos作为注册中心,源码在`registry-nacos`分支 |
||||
|
||||
这里演示如何将默认的eureka注册中心替换成nacos,步骤如下: |
||||
|
||||
- 准备工作 |
||||
|
||||
1.安装nacos,前往[最新稳定版本](https://github.com/alibaba/nacos/releases),下载最新版nacos |
||||
|
||||
2.启动nacos服务器,cd nacos/bin |
||||
|
||||
Linux/Unix/Mac,启动命令(standalone代表着单机模式运行,非集群模式): |
||||
|
||||
`sh startup.sh -m standalone` |
||||
|
||||
Windows,启动命令: |
||||
|
||||
`cmd startup.cmd` |
||||
|
||||
或者双击startup.cmd运行文件。 |
||||
|
||||
更多访问:https://nacos.io/zh-cn/docs/quick-start.html |
||||
|
||||
- 微服务端修改 |
||||
|
||||
1.修改微服务应用pom,打开`sop-example/sop-story/sop-story-web/pom.xml`,注释eureka服务发现依赖,添加nacos服务发现依赖 |
||||
|
||||
```xml |
||||
<!-- 注册中心【只能用一个,不用的注释掉】 --> |
||||
<!-- 使用eureka注册中心 |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> |
||||
</dependency> |
||||
--> |
||||
|
||||
<!-- 使用nacos注册中心 |
||||
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。 |
||||
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery |
||||
--> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> |
||||
<version>0.2.2.RELEASE</version> |
||||
</dependency> |
||||
<!-- 注册中心end --> |
||||
``` |
||||
|
||||
2.yml文件新增nacos配置,并注释掉eureka相关配置 |
||||
|
||||
```yaml |
||||
spring: |
||||
cloud: |
||||
# nacos注册中心,和eureka只能用一个 |
||||
nacos: |
||||
discovery: |
||||
server-addr: 127.0.0.1:8848 |
||||
``` |
||||
|
||||
- 网关修改 |
||||
|
||||
找到`sop-gateway`工程,步骤同上 |
||||
|
||||
- SOP-admin修改 |
||||
|
||||
|
||||
修改yml文件,设置nacos服务器地址,`registry.name`填nacos |
||||
|
||||
```yaml |
||||
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册 |
||||
registry: |
||||
eureka-server-addr: http://localhost:1111/eureka/ |
||||
# nacos服务器地址 |
||||
nacos-server-addr: 127.0.0.1:8848 |
||||
# 使用eureka,填:eureka,使用nacos填:nacos |
||||
name: nacos |
||||
``` |
||||
|
||||
- website-server修改 |
||||
|
||||
步骤同`SOP-admin修改` |
||||
|
||||
如果要改成consul注册中心,可参照以上步骤。 |
||||
|
||||
- 参考资料 |
||||
|
||||
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html) |
||||
|
||||
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html) |
@ -0,0 +1,112 @@ |
||||
# 扩展其它注册中心 |
||||
|
||||
**注: nacos注册中心已经实现,本篇以nacos为例介绍如何扩展,如果要改成consul,可按照此方式进行修改** |
||||
|
||||
SOP默认使用eureka注册中心,如果要换成nacos注册中心,步骤如下: |
||||
|
||||
- 实现`com.gitee.sop.registryapi.service.RegistryService`接口 |
||||
|
||||
1.找到`SOP/sop-common/sop-registry-api`工程,在service.impl包下新建一个类,实现RegistryService接口 |
||||
|
||||
```java |
||||
public class RegistryServiceNacos implements RegistryService { |
||||
|
||||
@Override |
||||
public List<ServiceInfo> listAllService(int pageNo, int pageSize) throws Exception { |
||||
// TODO: 返回服务实例 |
||||
} |
||||
|
||||
@Override |
||||
public void onlineInstance(ServiceInstance serviceInstance) throws Exception { |
||||
// TODO: 实例上线 |
||||
} |
||||
|
||||
@Override |
||||
public void offlineInstance(ServiceInstance serviceInstance) throws Exception { |
||||
// TODO: 实例下线 |
||||
} |
||||
} |
||||
``` |
||||
|
||||
2.在`com.gitee.sop.registryapi.config.BaseRegistryConfig`中新增 |
||||
|
||||
```java |
||||
/** |
||||
* 当配置了registry.name=nacos生效 |
||||
* |
||||
* @return |
||||
*/ |
||||
@Bean |
||||
@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos") |
||||
RegistryService registryServiceNacos() { |
||||
return new RegistryServiceNacos(); |
||||
} |
||||
``` |
||||
|
||||
其中`@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos")` |
||||
表示`application.properties`配置了`registry.name=nacos`参数才能生效,registry.name=nacos下文会讲到。 |
||||
|
||||
|
||||
- 微服务端修改 |
||||
|
||||
1.修改微服务应用pom.xml,注释eureka服务发现依赖,添加nacos服务发现依赖 |
||||
|
||||
```xml |
||||
<!-- 注册中心【只能用一个,不用的注释掉】 --> |
||||
<!-- 使用eureka注册中心 |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> |
||||
</dependency> |
||||
--> |
||||
|
||||
<!-- 使用nacos注册中心 |
||||
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。 |
||||
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery |
||||
--> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> |
||||
<version>0.2.2.RELEASE</version> |
||||
</dependency> |
||||
<!-- 注册中心end --> |
||||
``` |
||||
|
||||
2.yml文件新增nacos配置,并注释掉eureka相关配置 |
||||
|
||||
```yaml |
||||
spring: |
||||
cloud: |
||||
# nacos注册中心,和eureka只能用一个 |
||||
nacos: |
||||
discovery: |
||||
server-addr: 127.0.0.1:8848 |
||||
``` |
||||
|
||||
- 网关修改 |
||||
|
||||
找到`sop-gateway`工程,步骤同上 |
||||
|
||||
- SOP-admin修改 |
||||
|
||||
|
||||
修改yml文件,新增nacos服务器地址,`registry.name`填nacos |
||||
|
||||
```yaml |
||||
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册 |
||||
registry: |
||||
# 使用eureka,填:eureka,使用nacos填:nacos |
||||
name: nacos |
||||
eureka-server-addr: http://localhost:1111/eureka/ |
||||
nacos-server-addr: 127.0.0.1:8848 |
||||
``` |
||||
|
||||
- website-server修改 |
||||
|
||||
步骤同`SOP-admin修改` |
||||
|
||||
- 参考资料 |
||||
|
||||
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html) |
||||
|
||||
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html) |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,20 @@ |
||||
DROP TABLE IF EXISTS `isv_keys`; |
||||
|
||||
CREATE TABLE `isv_keys` ( |
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
||||
`app_key` varchar(128) NOT NULL DEFAULT '应用id(交给开发者)', |
||||
`sign_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1:RSA2,2:MD5', |
||||
`secret` varchar(200) NOT NULL DEFAULT '' COMMENT 'sign_type=2时使用', |
||||
`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 '平台生成的私钥', |
||||
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP, |
||||
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, |
||||
PRIMARY KEY (`id`), |
||||
UNIQUE KEY `uk_appkey` (`app_key`) USING BTREE |
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ISV秘钥'; |
||||
|
||||
INSERT INTO `sop`.`isv_keys` (`app_key`,`sign_type`, `secret`,`key_format`, `public_key_isv`, `private_key_isv`, `public_key_platform`, `private_key_platform`) |
||||
select app_key, sign_type, secret, 1, pub_key,pri_key,'','' from isv_info; |
@ -1,5 +1,5 @@ |
||||
# 后台admin |
||||
|
||||
- sop-admin-front: admin前端layui实现 |
||||
- sop-admin-front: admin前端layui实现(停止维护,改用sop-admin-vue) |
||||
- sop-admin-server: admin服务端 |
||||
- sop-admin-vue: admin前端vue实现 |
||||
|
@ -1,9 +1,7 @@ |
||||
# easyopen-server |
||||
|
||||
启动后,接口url:http://ip:port/api |
||||
|
||||
如果有contextPath的话则是:http://ip:port/contextPath/api |
||||
|
||||
业务类在api下,重点关注这里即可。 |
||||
# sop admin服务端 |
||||
|
||||
- 打开`application-dev.yml`,修改数据库`username/password` |
||||
- 运行`SopAdminServerApplication.java` |
||||
- 访问:`http://localhost:8082` |
||||
|
||||
登录账号:admin/123456 |
||||
|
@ -0,0 +1,47 @@ |
||||
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 tanghc |
||||
*/ |
||||
@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_isv */ |
||||
@ApiDocField(description = "开发者生成的公钥") |
||||
private String publicKeyIsv; |
||||
|
||||
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */ |
||||
@ApiDocField(description = "开发者生成的私钥") |
||||
private String privateKeyIsv; |
||||
|
||||
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */ |
||||
@ApiDocField(description = "平台生成的公钥") |
||||
private String publicKeyPlatform; |
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */ |
||||
@ApiDocField(description = "平台生成的私钥") |
||||
private String privateKeyPlatform; |
||||
} |
@ -0,0 +1,18 @@ |
||||
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 tanghc |
||||
*/ |
||||
@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; |
||||
} |
@ -0,0 +1,24 @@ |
||||
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 tanghc |
||||
*/ |
||||
@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; |
||||
} |
@ -0,0 +1,19 @@ |
||||
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 tanghc |
||||
*/ |
||||
@Getter |
||||
@Setter |
||||
public class RolePageParam extends PageParam { |
||||
@ApiDocField(description = "角色码") |
||||
@Condition(operator = Operator.like) |
||||
private String roleCode; |
||||
} |
@ -0,0 +1,11 @@ |
||||
package com.gitee.sop.adminserver.api.isv.result; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Data |
||||
public class IsvAppKeyGenVO { |
||||
private String appKey; |
||||
} |
@ -0,0 +1,34 @@ |
||||
package com.gitee.sop.adminserver.api.isv.result; |
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@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,23 +0,0 @@ |
||||
package com.gitee.sop.adminserver.api.isv.result; |
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Data |
||||
public class IsvFormVO { |
||||
@ApiDocField(description = "appKey", example = "aaaa") |
||||
private String appKey; |
||||
|
||||
@ApiDocField(description = "secret", example = "bbbb") |
||||
private String secret; |
||||
|
||||
@ApiDocField(description = "pubKey") |
||||
private String pubKey; |
||||
|
||||
@ApiDocField(description = "priKey") |
||||
private String priKey; |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
package com.gitee.sop.adminserver.api.isv.result; |
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@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; |
||||
|
||||
} |
@ -0,0 +1,38 @@ |
||||
package com.gitee.sop.adminserver.api.isv.result; |
||||
|
||||
import com.gitee.easyopen.doc.annotation.ApiDocField; |
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* @author thc |
||||
*/ |
||||
@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; |
||||
|
||||
} |
@ -0,0 +1,76 @@ |
||||
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 tanghc |
||||
*/ |
||||
@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; |
||||
|
||||
} |
@ -0,0 +1,22 @@ |
||||
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 tanghc |
||||
*/ |
||||
@Getter |
||||
@Setter |
||||
public class RouteDeleteParam { |
||||
@ApiDocField(description = "服务名serviceId") |
||||
@NotBlank(message = "serviceId不能为空") |
||||
private String serviceId; |
||||
|
||||
@ApiDocField(description = "路由id") |
||||
@NotBlank(message = "id不能为空") |
||||
private String id; |
||||
} |
@ -0,0 +1,21 @@ |
||||
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 tanghc |
||||
*/ |
||||
@Getter |
||||
@Setter |
||||
public class ServiceAddParam { |
||||
|
||||
@ApiDocField(description = "服务名serviceId") |
||||
@Length(max = 100, message = "长度不能超过100") |
||||
@NotBlank(message = "serviceId不能为空") |
||||
private String serviceId; |
||||
} |
@ -0,0 +1,54 @@ |
||||
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 tanghc |
||||
*/ |
||||
@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 lastUpdatedTimestamp; |
||||
|
||||
@ApiDocField(description = "parentId") |
||||
private Integer parentId; |
||||
|
||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss") |
||||
public Date getUpdateTime() { |
||||
if (StringUtils.isBlank(lastUpdatedTimestamp)) { |
||||
return null; |
||||
} |
||||
return new Date(Long.valueOf(lastUpdatedTimestamp)); |
||||
} |
||||
|
||||
public String getIpPort() { |
||||
return ip != null && port > 0 ? ip + ":" + port : ""; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,33 @@ |
||||
package com.gitee.sop.adminserver.common; |
||||
|
||||
import com.gitee.easyopen.exception.ApiException; |
||||
import com.gitee.easyopen.message.Error; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
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); |
||||
} |
||||
} |
@ -0,0 +1,410 @@ |
||||
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 tanghc |
||||
*/ |
||||
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 { |
||||
LENGTH_1024(1024), 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("---------------------"); |
||||
} |
||||
*/ |
||||
|
||||
} |
@ -0,0 +1,26 @@ |
||||
package com.gitee.sop.adminserver.common; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public class ZookeeperOperationException extends RuntimeException { |
||||
|
||||
public ZookeeperOperationException() { |
||||
} |
||||
|
||||
public ZookeeperOperationException(String message) { |
||||
super(message); |
||||
} |
||||
|
||||
public ZookeeperOperationException(String message, Throwable cause) { |
||||
super(message, cause); |
||||
} |
||||
|
||||
public ZookeeperOperationException(Throwable cause) { |
||||
super(cause); |
||||
} |
||||
|
||||
public ZookeeperOperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
||||
super(message, cause, enableSuppression, writableStackTrace); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
package com.gitee.sop.adminserver.common; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public class ZookeeperPathExistException extends Exception { |
||||
public ZookeeperPathExistException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
package com.gitee.sop.adminserver.common; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public class ZookeeperPathNotExistException extends Exception { |
||||
public ZookeeperPathNotExistException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,12 @@ |
||||
package com.gitee.sop.adminserver.config; |
||||
|
||||
import com.gitee.sop.registryapi.config.BaseRegistryConfig; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Configuration |
||||
public class RegistryConfig extends BaseRegistryConfig { |
||||
|
||||
} |
@ -0,0 +1,57 @@ |
||||
package com.gitee.sop.adminserver.entity; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.GeneratedValue; |
||||
import javax.persistence.GenerationType; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
import java.util.Date; |
||||
|
||||
|
||||
/** |
||||
* 表名:isv_keys |
||||
* 备注:ISV秘钥 |
||||
* |
||||
* @author tanghc |
||||
*/ |
||||
@Table(name = "isv_keys") |
||||
@Data |
||||
public class IsvKeys { |
||||
@Id |
||||
@Column(name = "id") |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
/** 数据库字段:id */ |
||||
private Long id; |
||||
|
||||
/** 数据库字段:app_key */ |
||||
private String appKey; |
||||
|
||||
/** 1:RSA2,2:MD5, 数据库字段:sign_type */ |
||||
private Byte signType; |
||||
|
||||
/** isv_info.sign_type=2时使用, 数据库字段:secret */ |
||||
private String secret; |
||||
|
||||
/** 秘钥格式,1:PKCS8(JAVA适用),2:PKCS1(非JAVA适用), 数据库字段:key_format */ |
||||
private Byte keyFormat; |
||||
|
||||
/** 开发者生成的公钥, 数据库字段:public_key_isv */ |
||||
private String publicKeyIsv; |
||||
|
||||
/** 开发者生成的私钥(交给开发者), 数据库字段:private_key_isv */ |
||||
private String privateKeyIsv; |
||||
|
||||
/** 平台生成的公钥(交给开发者), 数据库字段:public_key_platform */ |
||||
private String publicKeyPlatform; |
||||
|
||||
/** 平台生成的私钥, 数据库字段:private_key_platform */ |
||||
private String privateKeyPlatform; |
||||
|
||||
/** 数据库字段:gmt_create */ |
||||
private Date gmtCreate; |
||||
|
||||
/** 数据库字段:gmt_modified */ |
||||
private Date gmtModified; |
||||
} |
@ -0,0 +1,12 @@ |
||||
package com.gitee.sop.adminserver.mapper; |
||||
|
||||
import com.gitee.fastmybatis.core.mapper.CrudMapper; |
||||
|
||||
import com.gitee.sop.adminserver.entity.IsvKeys; |
||||
|
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public interface IsvKeysMapper extends CrudMapper<IsvKeys, Long> { |
||||
} |
@ -1 +1 @@ |
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,o,a=t[0],i=t[1],f=t[2],l=0,d=[];l<a.length;l++)o=a[l],c[o]&&d.push(c[o][0]),c[o]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);s&&s(t);while(d.length)d.shift()();return u.push.apply(u,f||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],r=!0,o=1;o<n.length;o++){var a=n[o];0!==c[a]&&(r=!1)}r&&(u.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={runtime:0},c={runtime:0},u=[];function a(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-19100986":"3ec98327","chunk-238a81e9":"5955f13d","chunk-29b24c82":"2b3ac7ca","chunk-2d0aa95b":"447435b3","chunk-2d221836":"574c9ab6","chunk-2d22c2e3":"46f37153","chunk-4a59cbe4":"b5e74cc4","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-19100986":1,"chunk-238a81e9":1,"chunk-29b24c82":1,"chunk-ea2e58a4":1};o[e]?t.push(o[e]):0!==o[e]&&n[e]&&t.push(o[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-19100986":"a43114f3","chunk-238a81e9":"e8e2beee","chunk-29b24c82":"857979fb","chunk-2d0aa95b":"31d6cfe0","chunk-2d221836":"31d6cfe0","chunk-2d22c2e3":"31d6cfe0","chunk-4a59cbe4":"31d6cfe0","chunk-ea2e58a4":"d10599db"}[e]+".css",c=i.p+r,u=document.getElementsByTagName("link"),a=0;a<u.length;a++){var f=u[a],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===c))return t()}var d=document.getElementsByTagName("style");for(a=0;a<d.length;a++){f=d[a],l=f.getAttribute("data-href");if(l===r||l===c)return t()}var s=document.createElement("link");s.rel="stylesheet",s.type="text/css",s.onload=t,s.onerror=function(t){var r=t&&t.target&&t.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=r,delete o[e],s.parentNode.removeChild(s),n(u)},s.href=c;var h=document.getElementsByTagName("head")[0];h.appendChild(s)}).then(function(){o[e]=0}));var r=c[e];if(0!==r)if(r)t.push(r[2]);else{var u=new Promise(function(t,n){r=c[e]=[t,n]});t.push(r[2]=u);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=a(e),f=function(t){l.onerror=l.onload=null,clearTimeout(d);var n=c[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src,u=new Error("Loading chunk "+e+" failed.\n("+r+": "+o+")");u.type=r,u.request=o,n[1](u)}c[e]=void 0}};var d=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var d=0;d<f.length;d++)t(f[d]);var s=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.36a3cb86.js></script></body></html> |
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function t(t){for(var r,c,a=t[0],i=t[1],f=t[2],l=0,d=[];l<a.length;l++)c=a[l],u[c]&&d.push(u[c][0]),u[c]=0;for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r]);h&&h(t);while(d.length)d.shift()();return o.push.apply(o,f||[]),n()}function n(){for(var e,t=0;t<o.length;t++){for(var n=o[t],r=!0,c=1;c<n.length;c++){var a=n[c];0!==u[a]&&(r=!1)}r&&(o.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(e){return i.p+"static/js/"+({}[e]||e)+"."+{"chunk-009073d4":"28312808","chunk-238a81e9":"5955f13d","chunk-25908fca":"9d8bc0b6","chunk-29e7142c":"994a3ac0","chunk-2d2085ef":"a63a74dc","chunk-2d22c2e3":"4a098244","chunk-37401378":"4e39ec9b","chunk-4a59cbe4":"a6360c68","chunk-6a68a33e":"b6685cb9","chunk-73b2dcec":"14f248eb"}[e]+".js"}function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.e=function(e){var t=[],n={"chunk-009073d4":1,"chunk-238a81e9":1,"chunk-25908fca":1,"chunk-29e7142c":1,"chunk-37401378":1,"chunk-6a68a33e":1,"chunk-73b2dcec":1};c[e]?t.push(c[e]):0!==c[e]&&n[e]&&t.push(c[e]=new Promise(function(t,n){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-009073d4":"0af16c7e","chunk-238a81e9":"e8e2beee","chunk-25908fca":"89ab33e8","chunk-29e7142c":"d10599db","chunk-2d2085ef":"31d6cfe0","chunk-2d22c2e3":"31d6cfe0","chunk-37401378":"a43114f3","chunk-4a59cbe4":"31d6cfe0","chunk-6a68a33e":"3b12267b","chunk-73b2dcec":"99cf6327"}[e]+".css",u=i.p+r,o=document.getElementsByTagName("link"),a=0;a<o.length;a++){var f=o[a],l=f.getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(l===r||l===u))return t()}var d=document.getElementsByTagName("style");for(a=0;a<d.length;a++){f=d[a],l=f.getAttribute("data-href");if(l===r||l===u)return t()}var h=document.createElement("link");h.rel="stylesheet",h.type="text/css",h.onload=t,h.onerror=function(t){var r=t&&t.target&&t.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],h.parentNode.removeChild(h),n(o)},h.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(h)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)t.push(r[2]);else{var o=new Promise(function(t,n){r=u[e]=[t,n]});t.push(r[2]=o);var f,l=document.createElement("script");l.charset="utf-8",l.timeout=120,i.nc&&l.setAttribute("nonce",i.nc),l.src=a(e),f=function(t){l.onerror=l.onload=null,clearTimeout(d);var n=u[e];if(0!==n){if(n){var r=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,n[1](o)}u[e]=void 0}};var d=setTimeout(function(){f({type:"timeout",target:l})},12e4);l.onerror=l.onload=f,document.head.appendChild(l)}return Promise.all(t)},i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i.oe=function(e){throw console.error(e),e};var f=window["webpackJsonp"]=window["webpackJsonp"]||[],l=f.push.bind(f);f.push=t,f=f.slice();for(var d=0;d<f.length;d++)t(f[d]);var h=l;n()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.095e8b9c.js></script></body></html> |
@ -0,0 +1 @@ |
||||
.custom-tree-node{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:14px;padding-right:8px}.el-input.is-disabled .el-input__inner,.el-radio__input.is-disabled+span.el-radio__label{color:#909399}.limit-tip[data-v-b81bfbde]{cursor:pointer;margin-left:10px} |
@ -0,0 +1 @@ |
||||
.gen-key{margin-bottom:0!important}fieldset{border:1px solid #ccc;color:grey;margin-left:40px;margin-bottom:20px}fieldset label{width:110px!important}fieldset .el-form-item__content{margin-left:110px!important}.key-view .el-form-item{margin-bottom:10px!important} |
@ -1 +0,0 @@ |
||||
.limit-tip[data-v-29df7fee]{cursor:pointer;margin-left:10px} |
@ -0,0 +1 @@ |
||||
.custom-tree-node{-webkit-box-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:14px;padding-right:8px}.el-input.is-disabled .el-input__inner,.el-radio__input.is-disabled+span.el-radio__label{color:#909399} |
@ -0,0 +1 @@ |
||||
.gen-key{margin-bottom:0!important}fieldset{border:1px solid #ccc;color:grey;margin-left:40px;margin-bottom:20px}fieldset label{width:110px!important}fieldset .el-form-item__content{margin-left:110px!important} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@ |
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d22c2e3"],{f1ac:function(t,e,a){"use strict";a.r(e);var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"app-container"},[a("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[a("el-form-item",{attrs:{label:"serviceId"}},[a("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"serviceId"},model:{value:t.searchFormData.serviceId,callback:function(e){t.$set(t.searchFormData,"serviceId",e)},expression:"searchFormData.serviceId"}})],1),t._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),a("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"id"}},[a("el-table-column",{attrs:{prop:"name",label:"服务名称(serviceId)",width:"200"}}),t._v(" "),a("el-table-column",{attrs:{prop:"instanceId",label:"instanceId",width:"250"}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddr",label:"IP地址",width:"150"}}),t._v(" "),a("el-table-column",{attrs:{prop:"serverPort",label:"端口号",width:"100"}}),t._v(" "),a("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-tag",{attrs:{type:"success"}},[t._v("已上线")]):t._e(),t._v(" "),e.row.parentId>0&&"STARTING"===e.row.status?a("el-tag",{attrs:{type:"info"}},[t._v("正在启动")]):t._e(),t._v(" "),e.row.parentId>0&&"UNKNOWN"===e.row.status?a("el-tag",[t._v("未知")]):t._e(),t._v(" "),e.row.parentId>0&&("OUT_OF_SERVICE"===e.row.status||"DOWN"===e.row.status)?a("el-tag",{attrs:{type:"danger"}},[t._v("已下线")]):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),t._v(" "),a("el-table-column",{attrs:{label:"操作",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOffline(e.row)}}},[t._v("下线")]):t._e(),t._v(" "),e.row.parentId>0&&"OUT_OF_SERVICE"===e.row.status?a("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(a){return t.onOnline(e.row)}}},[t._v("上线")]):t._e()]}}])})],1)],1)},r=[],i=(a("7f7f"),a("ac6a"),{data:function(){return{searchFormData:{serviceId:""},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(t){this.tableData=this.buildTreeData(t.data)})},buildTreeData:function(t){return t.forEach(function(e){var a=e.parentId;0===a||t.forEach(function(t){if(t.id===a){var n=t.children;n||(n=[]),n.push(e),t.children=n}})}),t=t.filter(function(t){return 0===t.parentId}),t},onSearchTable:function(){this.loadTable()},onOffline:function(t){this.confirm("确定要下线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.offline",a,function(){this.tip("下线成功"),e()})})},onOnline:function(t){this.confirm("确定要上线【"+t.name+"】吗?",function(e){var a={serviceId:t.name,instanceId:t.instanceId};this.post("service.instance.online",a,function(){this.tip("上线成功"),e()})})}}}),s=i,o=a("2877"),l=Object(o["a"])(s,n,r,!1,null,null,null);e["default"]=l.exports}}]); |
@ -0,0 +1 @@ |
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d22c2e3"],{f1ac:function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"app-container"},[n("el-form",{staticClass:"demo-form-inline",attrs:{inline:!0,model:t.searchFormData,size:"mini"}},[n("el-form-item",{attrs:{label:"serviceId"}},[n("el-input",{staticStyle:{width:"250px"},attrs:{clearable:!0,placeholder:"serviceId"},model:{value:t.searchFormData.serviceId,callback:function(e){t.$set(t.searchFormData,"serviceId",e)},expression:"searchFormData.serviceId"}})],1),t._v(" "),n("el-form-item",[n("el-button",{attrs:{type:"primary",icon:"el-icon-search"},on:{click:t.onSearchTable}},[t._v("查询")])],1)],1),t._v(" "),n("el-table",{staticStyle:{width:"100%","margin-bottom":"20px"},attrs:{data:t.tableData,border:"","row-key":"id"}},[n("el-table-column",{attrs:{prop:"serviceId",label:"服务名称",width:"200"},scopedSlots:t._u([{key:"default",fn:function(e){return[n("span",{domProps:{innerHTML:t._s(t.renderServiceName(e.row))}})]}}])}),t._v(" "),n("el-table-column",{attrs:{prop:"ipPort",label:"IP端口",width:"250"}}),t._v(" "),n("el-table-column",{attrs:{prop:"status",label:"服务状态",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?n("el-tag",{attrs:{type:"success"}},[t._v("已上线")]):t._e(),t._v(" "),e.row.parentId>0&&"STARTING"===e.row.status?n("el-tag",{attrs:{type:"info"}},[t._v("正在启动")]):t._e(),t._v(" "),e.row.parentId>0&&"UNKNOWN"===e.row.status?n("el-tag",[t._v("未知")]):t._e(),t._v(" "),e.row.parentId>0&&("OUT_OF_SERVICE"===e.row.status||"DOWN"===e.row.status)?n("el-tag",{attrs:{type:"danger"}},[t._v("已下线")]):t._e()]}}])}),t._v(" "),n("el-table-column",{attrs:{prop:"updateTime",label:"最后更新时间",width:"160"}}),t._v(" "),n("el-table-column",{attrs:{label:"操作",width:"100"},scopedSlots:t._u([{key:"default",fn:function(e){return[e.row.parentId>0&&"UP"===e.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return t.onOffline(e.row)}}},[t._v("下线")]):t._e(),t._v(" "),e.row.parentId>0&&"OUT_OF_SERVICE"===e.row.status?n("el-button",{attrs:{type:"text",size:"mini"},on:{click:function(n){return t.onOnline(e.row)}}},[t._v("上线")]):t._e()]}}])})],1)],1)},r=[],i=(n("ac6a"),{data:function(){return{searchFormData:{serviceId:""},tableData:[]}},created:function(){this.loadTable()},methods:{loadTable:function(){this.post("service.instance.list",this.searchFormData,function(t){this.tableData=this.buildTreeData(t.data)})},buildTreeData:function(t){return t.forEach(function(e){var n=e.parentId;0===n||t.forEach(function(t){if(t.id===n){var a=t.children;a||(a=[]),a.push(e),t.children=a}})}),t=t.filter(function(t){return 0===t.parentId}),t},onSearchTable:function(){this.loadTable()},onOffline:function(t){this.confirm("确定要下线【"+t.serviceId+"】吗?",function(e){this.post("service.instance.offline",t,function(){this.tip("下线成功"),e()})})},onOnline:function(t){this.confirm("确定要上线【"+t.serviceId+"】吗?",function(e){this.post("service.instance.online",t,function(){this.tip("上线成功"),e()})})},renderServiceName:function(t){var e="";if(t.children&&t.children.length>0){var n=t.children.filter(function(t){return"UP"===t.status}).length;e=" (".concat(n,"/").concat(t.children.length,")")}return t.serviceId+e}}}),o=i,s=n("2877"),l=Object(s["a"])(o,a,r,!1,null,null,null);e["default"]=l.exports}}]); |
@ -1 +1 @@ |
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-19100986"],{5040:function(t,n,a){"use strict";var e=a("a5a4"),s=a.n(e);s.a},9406:function(t,n,a){"use strict";a.r(n);var e=function(){var t=this,n=t.$createElement;t._self._c;return t._m(0)},s=[function(){var t=this,n=t.$createElement,a=t._self._c||n;return a("div",{staticClass:"dashboard-container"},[a("div",{staticClass:"dashboard-text"},[t._v("欢迎使用SOP Admin")])])}],i={created:function(){this.post("admin.userinfo.get",{},function(t){})}},c=i,r=(a("5040"),a("2877")),o=Object(r["a"])(c,e,s,!1,null,"b4bd5162",null);n["default"]=o.exports},a5a4:function(t,n,a){}}]); |
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-37401378"],{5040:function(t,n,a){"use strict";var e=a("a5a4"),s=a.n(e);s.a},9406:function(t,n,a){"use strict";a.r(n);var e=function(){var t=this,n=t.$createElement;t._self._c;return t._m(0)},s=[function(){var t=this,n=t.$createElement,a=t._self._c||n;return a("div",{staticClass:"dashboard-container"},[a("div",{staticClass:"dashboard-text"},[t._v("欢迎使用SOP Admin")])])}],i={created:function(){this.post("admin.userinfo.get",{},function(t){})}},c=i,r=(a("5040"),a("2877")),o=Object(r["a"])(c,e,s,!1,null,"b4bd5162",null);n["default"]=o.exports},a5a4:function(t,n,a){}}]); |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,45 @@ |
||||
package com.gitee.sop.adminserver; |
||||
|
||||
import com.gitee.sop.adminserver.bean.SopAdminConstants; |
||||
import junit.framework.TestCase; |
||||
import org.apache.curator.framework.CuratorFramework; |
||||
import org.apache.curator.framework.CuratorFrameworkFactory; |
||||
import org.apache.curator.retry.ExponentialBackoffRetry; |
||||
import org.apache.zookeeper.data.Stat; |
||||
|
||||
public class CuratorTest extends TestCase { |
||||
|
||||
private static String zookeeperServerAddr = "localhost:2181"; |
||||
|
||||
static CuratorFramework client; |
||||
|
||||
public CuratorTest() { |
||||
client = CuratorFrameworkFactory.builder() |
||||
.connectString(zookeeperServerAddr) |
||||
.retryPolicy(new ExponentialBackoffRetry(1000, 3)) |
||||
.build(); |
||||
|
||||
client.start(); |
||||
} |
||||
|
||||
/** |
||||
* 递归删除节点,只能在测试环境用。 |
||||
* |
||||
* @throws Exception |
||||
*/ |
||||
public void testDel() { |
||||
try { |
||||
client.delete() |
||||
.deletingChildrenIfNeeded() |
||||
.forPath(SopAdminConstants.RELOAD_ROUTE_PERMISSION_PATH); |
||||
} catch (Exception e) { |
||||
} |
||||
} |
||||
|
||||
public void testCheck() throws Exception { |
||||
String path = SopAdminConstants.RELOAD_ROUTE_PERMISSION_PATH + "/1562231019332"; |
||||
Stat stat = client.checkExists().forPath(path); |
||||
System.out.println(path + (stat == null ? "不存在" : "存在")); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,21 @@ |
||||
package com.gitee.sop.adminserver; |
||||
|
||||
import com.gitee.sop.adminserver.api.isv.result.IsvDetailDTO; |
||||
import com.gitee.sop.adminserver.mapper.IsvInfoMapper; |
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public class IsvInfoMapperTest extends SopAdminServerApplicationTests { |
||||
|
||||
@Autowired |
||||
IsvInfoMapper isvInfoMapper; |
||||
|
||||
@Test |
||||
public void testGet() { |
||||
IsvDetailDTO isvDetail = isvInfoMapper.getIsvDetail("2019032617262200001"); |
||||
System.out.println(isvDetail); |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package com.gitee.durcframework.easyopen.server; |
||||
package com.gitee.sop.adminserver; |
||||
|
||||
import org.junit.Test; |
||||
|
@ -1,4 +1,4 @@ |
||||
package com.gitee.durcframework.easyopen.server; |
||||
package com.gitee.sop.adminserver; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
@ -1,4 +1,4 @@ |
||||
package com.gitee.durcframework.easyopen.server; |
||||
package com.gitee.sop.adminserver; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue