Merge remote-tracking branch 'origin/master' into workflow_support
# Conflicts: # pom.xml
This commit is contained in:
commit
e211ab25d3
|
@ -0,0 +1,65 @@
|
|||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 https://maven.apache.org/xsd/assembly-2.2.0.xsd">
|
||||
<id>${project.version}</id>
|
||||
<formats>
|
||||
<format>tgz</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./target/</directory>
|
||||
<includes>
|
||||
<include>MiddlewareAgent.jar</include>
|
||||
</includes>
|
||||
<outputDirectory>${file.separator}</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>./config</directory>
|
||||
<outputDirectory>${file.separator}config</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<outputDirectory>${file.separator}bin</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../</directory>
|
||||
<outputDirectory>${file.separator}</outputDirectory>
|
||||
<includes>
|
||||
<include>../CHANGELOG.md</include>
|
||||
<include>../README.md</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/git.properties</exclude>
|
||||
<exclude>**/smart-doc.json</exclude>
|
||||
<exclude>**/db/**</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>${file.separator}</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<scope>provided</scope>
|
||||
</dependencySet>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<scope>system</scope>
|
||||
</dependencySet>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<scope>runtime</scope>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=n "
|
||||
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false "
|
||||
JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -server -Xms512M -Xmx512M -Xss256K -XX:MetaspaceSize=16M -XX:MaxMetaspaceSize=128M -XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=8 -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof"
|
||||
WORK_PATH=$(cd `dirname $0`; pwd)
|
||||
cd $WORK_PATH
|
||||
cd ..
|
||||
$JAVA_HOME/bin/java $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $JAVA_OPTS -jar MiddlewareAgent.jar &
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
APP_NAME=CommonFramework-exec
|
||||
|
||||
pids=`ps -ef | grep $APP_NAME | grep -v grep | awk '{print $2}'`
|
||||
for pid in $pids
|
||||
do
|
||||
echo stop $APP_NAME java process: $pid
|
||||
kill -9 $pid
|
||||
done
|
||||
|
||||
nr_pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
|
||||
while [ $nr_pids -gt 0 ]
|
||||
do
|
||||
nr_pids=`ps -ef | grep $APP_NAME | grep -v grep | wc -l`
|
||||
done
|
|
@ -1,7 +1,9 @@
|
|||
package com.cmcc.magent;
|
||||
|
||||
import com.cmcc.hy.gzs.common.sign.autoconfigure.EnableSign;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
|
@ -28,6 +30,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||
*/
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@EnableFeignClients
|
||||
@EnableSign
|
||||
public class MiddlewareAgentApplication {
|
||||
|
||||
/**
|
||||
|
|
|
@ -190,7 +190,7 @@ public class CommonConfigure {
|
|||
log.error("Unable get local ip address: {}", e.getMessage());
|
||||
} finally {
|
||||
setGlobalVars(serverProperties.getServlet().getContextPath(),
|
||||
"http://" + addr + ":" + serverProperties.getPort() + serverProperties.getServlet().getContextPath(),
|
||||
"https://" + addr + ":" + serverProperties.getPort() + serverProperties.getServlet().getContextPath(),
|
||||
addr,
|
||||
serverProperties.getPort());
|
||||
log.info("baseUrl: {}", BASEURL);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.cmcc.magent.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* MwCoreConfig类用于配置与中间件核心相关的属性。
|
||||
*
|
||||
* <p>该类包含客户端ID和客户端密钥,用于与GZS服务进行身份验证。</p>
|
||||
*
|
||||
* <p>该配置类会在Spring容器启动时加载,并支持动态刷新配置。</p>
|
||||
*
|
||||
* @author huangxin@cmhi.chinamobile.com
|
||||
* @version 1.0.0
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
@Component
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "mw.agent")
|
||||
@Data
|
||||
public class MwCoreConfig {
|
||||
|
||||
/**
|
||||
* 内部客户端ID。
|
||||
*
|
||||
* <p>默认为"mw-open-82hsbmz8",可通过配置文件进行覆盖。</p>
|
||||
*/
|
||||
private String innerClientId = "mw-open-82hsbmz8";
|
||||
|
||||
/**
|
||||
* 内部客户端密钥。
|
||||
*
|
||||
* <p>默认为"98rnk8pz6j08fp6q",可通过配置文件进行覆盖。</p>
|
||||
*/
|
||||
private String innerClientSecret = "98rnk8pz6j08fp6q";
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.cmcc.magent.interceptor;
|
||||
|
||||
import com.cmcc.hy.gzs.common.feign.GzsSignRequestInterceptor;
|
||||
import com.cmcc.magent.config.MwCoreConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* MwSignRequestInterceptor类实现了GzsSignRequestInterceptor接口。
|
||||
*
|
||||
* <p>该类用于拦截请求并提供客户端ID和客户端密钥,用于与GZS服务的身份验证。</p>
|
||||
*
|
||||
* @author huangxin@cmhi.chinamobile.com
|
||||
* @version 1.0.0
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MwSignRequestInterceptor implements GzsSignRequestInterceptor {
|
||||
|
||||
private final MwCoreConfig mwCoreProperties;
|
||||
|
||||
/**
|
||||
* 获取客户端ID。
|
||||
*
|
||||
* @return 客户端ID
|
||||
*/
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return mwCoreProperties.getInnerClientId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端密钥。
|
||||
*
|
||||
* @return 客户端密钥
|
||||
*/
|
||||
@Override
|
||||
public String getClientSecret() {
|
||||
return mwCoreProperties.getInnerClientSecret();
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.cmcc.magent.pojo.dto;
|
|||
|
||||
import com.cmcc.magent.pojo.po.RemoteFileDetails;
|
||||
import com.cmcc.magent.validation.group.ValidGroups;
|
||||
import com.cmcc.magent.validation.valids.ValidFixValues;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
@ -34,7 +33,6 @@ public class DeployMiddlewareFileReq {
|
|||
* 中间件类型,不能为空,并且必须是指定的固定值之一(Redis, Nginx, Keepalived)。
|
||||
*/
|
||||
@NotBlank(message = "middleware Not Blank", groups = {ValidGroups.MiddlewareDeploymentReqValid.class})
|
||||
@ValidFixValues(value = {"Redis", "Nginx", "Keepalived"}, ignoreSwitchCase = true, groups = {ValidGroups.MiddlewareDeploymentReqValid.class})
|
||||
private String middleware;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.cmcc.magent.pojo.dto;
|
|||
|
||||
import com.cmcc.magent.pojo.po.RemoteFileDetails;
|
||||
import com.cmcc.magent.validation.group.ValidGroups;
|
||||
import com.cmcc.magent.validation.valids.ValidFixValues;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
@ -34,7 +33,6 @@ public class DeploymentMiddlewareReq {
|
|||
* 中间件类型,不能为空,并且必须是指定的固定值之一(Redis, Nginx, Keepalived)。
|
||||
*/
|
||||
@NotBlank(message = "middleware Not Blank", groups = {ValidGroups.MiddlewareDeploymentReqValid.class})
|
||||
@ValidFixValues(value = {"Redis", "Nginx", "Keepalived"}, ignoreSwitchCase = true, groups = {ValidGroups.MiddlewareDeploymentReqValid.class})
|
||||
private String middleware;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.cmcc.magent.service;
|
||||
|
||||
import com.cmcc.hy.gzs.common.result.Result;
|
||||
import com.cmcc.magent.interceptor.MwSignRequestInterceptor;
|
||||
import com.cmcc.magent.pojo.po.RegisterAgent;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* PlatformApiFeignClientService 接口定义了与平台 API 通信的核心服务功能。
|
||||
* <p>
|
||||
* 该接口包含与平台交互的关键操作,具体实现类负责与平台进行数据交互。
|
||||
* </p>
|
||||
*
|
||||
* @author huangxin@cmhi.chinamobile.com
|
||||
* @version 1.0.0
|
||||
* @since 2025-03-10
|
||||
*/
|
||||
@FeignClient(name = "agent-portal-feign",
|
||||
url = "${service.platform-url}",
|
||||
path = "/mw/core",
|
||||
configuration = MwSignRequestInterceptor.class)
|
||||
public interface PlatformApiFeignClientService {
|
||||
|
||||
/**
|
||||
* 注册代理。
|
||||
*
|
||||
* @param agent 要注册的代理信息,包含代理的相关属性。
|
||||
* @return 返回一个 {@link Result} 对象,包含注册结果的状态和消息。
|
||||
*/
|
||||
@PostMapping(path = "/register", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
Result<String> registerAgentFeign(@RequestBody RegisterAgent agent);
|
||||
|
||||
|
||||
/**
|
||||
* 响应部署结果。
|
||||
*
|
||||
* <p>该方法用于更新指定部署的状态,服务器将根据传入的状态信息进行相应处理。</p>
|
||||
*
|
||||
* @param deploymentId 部署的唯一标识符,用于指定需要更新状态的部署。
|
||||
* @param status 部署状态,整数类型,表示当前部署的状态,如成功、失败等。
|
||||
* @return 返回一个 {@link Result} 对象,包含操作结果的状态和相关信息。
|
||||
*
|
||||
*/
|
||||
@PostMapping(path = "/innerapi/instance/update-status",
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
Result<String> responseDeploymentResultFeign(@RequestParam("deploymentId") String deploymentId, @RequestParam("status") Integer status);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package com.cmcc.magent.service;
|
||||
|
||||
import com.cmcc.hy.gzs.common.result.Result;
|
||||
import com.cmcc.magent.pojo.po.RegisterAgent;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* PlatformApiService 接口定义了与平台 API 通信的核心服务功能。
|
||||
|
@ -15,16 +15,23 @@ import java.io.IOException;
|
|||
* @since 2025-01-07
|
||||
*/
|
||||
public interface PlatformApiService {
|
||||
/**
|
||||
* 注册代理。
|
||||
*
|
||||
* @param agent 要注册的代理信息,包含代理的相关属性。
|
||||
* @return 返回一个 {@link Result} 对象,包含注册结果的状态和消息。
|
||||
*/
|
||||
Result<String> registerAgent(@RequestBody RegisterAgent agent);
|
||||
|
||||
/**
|
||||
* 注册代理(Agent)。
|
||||
* <p>
|
||||
* 该方法用于将代理实例注册到平台,并返回平台生成的响应结果。
|
||||
* </p>
|
||||
* 响应部署结果。
|
||||
*
|
||||
* <p>该方法用于更新指定部署的状态,服务器将根据传入的状态信息进行相应处理。</p>
|
||||
*
|
||||
* @param deploymentId 部署的唯一标识符,用于指定需要更新状态的部署。
|
||||
* @param status 部署状态,整数类型,表示当前部署的状态,如成功、失败等。
|
||||
* @return 返回一个 {@link Result} 对象,包含操作结果的状态和相关信息。
|
||||
*
|
||||
* @param agent 包含代理注册信息的 {@link RegisterAgent} 对象
|
||||
* @return 平台返回的结果,通常为一个 JSON 格式的字符串
|
||||
* @throws IOException 如果在处理 JSON 时发生错误
|
||||
*/
|
||||
String registerAgent(RegisterAgent agent) throws IOException;
|
||||
Result<String> responseDeploymentResult(String deploymentId, Integer status);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.cmcc.magent.pojo.po.LocalShellContext;
|
|||
import com.cmcc.magent.pojo.po.RemoteFileContext;
|
||||
import com.cmcc.magent.pojo.po.RemoteFileDetails;
|
||||
import com.cmcc.magent.service.MiddlewareManagerService;
|
||||
import com.cmcc.magent.service.PlatformApiService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -64,6 +65,9 @@ public class MiddlewareManagerServiceImpl implements MiddlewareManagerService {
|
|||
@Resource
|
||||
private OssFactory ossFactory;
|
||||
|
||||
@Resource
|
||||
private PlatformApiService platformApiService;
|
||||
|
||||
/**
|
||||
* 根据命令获取对应的文件名。
|
||||
*
|
||||
|
@ -363,6 +367,13 @@ public class MiddlewareManagerServiceImpl implements MiddlewareManagerService {
|
|||
}
|
||||
runCommand(workDir, command);
|
||||
log.info("---- Task {} Finished", data.getUid());
|
||||
}).whenComplete((v, t) -> {
|
||||
if (t != null) {
|
||||
platformApiService.responseDeploymentResult(data.getUid(), 2);
|
||||
log.error("---- Task {} Finished With Exception: {}", data.getUid(), t.getMessage());
|
||||
} else {
|
||||
log.info("---- Task {} Finished: {}", data.getUid(), platformApiService.responseDeploymentResult(data.getUid(), 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -440,6 +451,13 @@ public class MiddlewareManagerServiceImpl implements MiddlewareManagerService {
|
|||
|
||||
runCommand(workDir, cmd);
|
||||
log.info("---- Task {} Finished", data.getUid());
|
||||
}).whenComplete((v, t) -> {
|
||||
if (t != null) {
|
||||
platformApiService.responseDeploymentResult(data.getUid(), 2);
|
||||
log.error("---- Task {} Finished With Exception: {}", data.getUid(), t.getMessage());
|
||||
} else {
|
||||
log.info("---- Task {} Finished: {}", data.getUid(), platformApiService.responseDeploymentResult(data.getUid(), 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package com.cmcc.magent.service.impl;
|
||||
|
||||
import com.cmcc.magent.config.PlatformServiceConfig;
|
||||
import com.cmcc.magent.misc.HttpClientUtils;
|
||||
import com.cmcc.magent.misc.JsonUtils;
|
||||
import com.cmcc.hy.gzs.common.result.Result;
|
||||
import com.cmcc.magent.pojo.po.RegisterAgent;
|
||||
import com.cmcc.magent.service.PlatformApiFeignClientService;
|
||||
import com.cmcc.magent.service.PlatformApiService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* PlatformApiServiceImpl 是 {@link PlatformApiService} 的具体实现类。
|
||||
* PlatformApiServiceImpl 是 {@link PlatformApiFeignClientService} 的具体实现类。
|
||||
* <p>
|
||||
* 该类使用 与平台 API 进行交互,提供了注册代理的功能。
|
||||
* </p>
|
||||
|
@ -26,24 +24,50 @@ import java.io.IOException;
|
|||
* @since 2025 -01-07
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PlatformApiServiceImpl implements PlatformApiService {
|
||||
@Resource
|
||||
private PlatformServiceConfig platformServiceConfig;
|
||||
private PlatformApiFeignClientService platformApiServiceFeign;
|
||||
|
||||
/**
|
||||
* 注册代理(Agent)。
|
||||
* <p>
|
||||
* 通过向平台 API 提供的注册接口("/register")发送 POST 请求,完成代理的注册操作。
|
||||
* 请求体为转换为 JSON 格式的 {@link RegisterAgent} 对象。
|
||||
* </p>
|
||||
* 注册代理。
|
||||
*
|
||||
* @param agent 包含代理注册信息的 {@link RegisterAgent} 实例
|
||||
* @return 平台返回的注册结果,通常为 JSON 格式的字符串
|
||||
* @throws IOException IO 异常
|
||||
* @param agent 要注册的代理信息,包含代理的相关属性。
|
||||
* @return 返回一个 {@link Result} 对象,包含注册结果的状态和消息。
|
||||
*/
|
||||
@Override
|
||||
public String registerAgent(RegisterAgent agent) throws IOException {
|
||||
String reqString = JsonUtils.getJson(agent);
|
||||
return HttpClientUtils.postJson(platformServiceConfig + "/register", null, reqString, null);
|
||||
public Result<String> registerAgent(RegisterAgent agent) {
|
||||
Result<String> s = null;
|
||||
|
||||
try {
|
||||
s = platformApiServiceFeign.registerAgentFeign(agent);
|
||||
} catch (Exception e) {
|
||||
log.error("Register agent client {} exception: {}", agent.getDeviceId(), e.getMessage());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应部署结果。
|
||||
*
|
||||
* <p>该方法用于更新指定部署的状态,服务器将根据传入的状态信息进行相应处理。</p>
|
||||
*
|
||||
* @param deploymentId 部署的唯一标识符,用于指定需要更新状态的部署。
|
||||
* @param status 部署状态,整数类型,表示当前部署的状态,如成功、失败等。
|
||||
* @return 返回一个 {@link Result} 对象,包含操作结果的状态和相关信息。
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Result<String> responseDeploymentResult(String deploymentId, Integer status) {
|
||||
Result<String> s = null;
|
||||
|
||||
try {
|
||||
s = platformApiServiceFeign.responseDeploymentResultFeign(deploymentId, status);
|
||||
} catch (Exception e) {
|
||||
log.error("Response deployment {} result exception: {}", deploymentId, e.getMessage());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,16 @@ server.compression.enabled=true
|
|||
server.compression.mime-types=application/json
|
||||
server.compression.min-response-size=1KB
|
||||
|
||||
|
||||
server.ssl.key-store-type=PKCS12
|
||||
server.ssl.key-store=classpath:certs/keystore.p12
|
||||
server.ssl.key-store-password=101010
|
||||
server.ssl.key-alias=tomcat
|
||||
|
||||
|
||||
server.undertow.buffer-size=1024
|
||||
server.undertow.max-http-post-size=10MB
|
||||
|
||||
# Spring Web Configuration
|
||||
spring.web.resources.add-mappings=false
|
||||
|
||||
|
@ -70,7 +80,7 @@ protocol.crypto-type=0
|
|||
|
||||
# Platform Service
|
||||
# Manager Platform URL
|
||||
service.platform-url=http://xajhuang.com:1300
|
||||
service.platform-url=https://172.21.44.35:50443/mw/core
|
||||
# APPID
|
||||
service.platform-appid=appid
|
||||
# cluster name
|
||||
|
@ -84,3 +94,21 @@ thread.max-pool-size=10
|
|||
thread.queue-capacity=25
|
||||
thread.name-prefix=Async-
|
||||
|
||||
# Can support profiles, databases, or remote
|
||||
gzs.sign.client-details-enabled=true
|
||||
gzs.sign.client-details.'mw-open-82hsbmz8'=98rnk8pz6j08fp6q
|
||||
# Permission: Specifies the interface corresponding to client_id. If the default value is empty, there is no restriction.
|
||||
#gzs.sign.perm.'yj-yy-1234567'=/xx/xx,/xx/yy
|
||||
|
||||
# default can be configured in the rule-group, for example, gzs.sign.rule-.yj.mode =0
|
||||
# [Optional] 1: strict mode, 0: common mode (default)
|
||||
#gzs.sign.rule.default.mode=0
|
||||
# [Optional] Mandatory check list (In any mode, the following interfaces require check)
|
||||
gzs.sign.rule.default.required-list=POST:/xxx/xx,*:/xxx/yy/**
|
||||
# [Optional] Optional check list (In any mode, the following interfaces can be checked)
|
||||
#gzs.sign.rule.default.optional-list=GET:/xxx/xx,*:/xxx/yy/*
|
||||
|
||||
# [Optional] If base64 encoding is used, you can configure whether base64 encoding for url security is required in the signature algorithm based on different client_id. The default value is true
|
||||
#gzs.sign.base64-url-safe.def = true
|
||||
#gzs.sign.base64-url-safe.'as-xx-1234567' = false
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIG/zCCBeegAwIBAgIIUPS1tguj0LAwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV
|
||||
BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow
|
||||
GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz
|
||||
LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1
|
||||
cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMjMwNjA4MDc0ODQ5WhcN
|
||||
MjQwNzA5MDc0ODQ5WjCBgTELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCea1meaxn+ec
|
||||
gTESMBAGA1UEBwwJ5p2t5bee5biCMTMwMQYDVQQKDCrkuK3np7vvvIjmna3lt57v
|
||||
vInkv6Hmga/mioDmnK/mnInpmZDlhazlj7gxFTATBgNVBAMMDCoua29tZWN0LmNv
|
||||
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALgQ3fh8pvHAn7NCkZxJ
|
||||
q1VygM8DWR7qCZS55bMqaqceFdrly+bB+80WKfddXncD1pUKQ77SNsEZyC1DT+Ei
|
||||
mOro8GITVl/iuZc6QtDM/ZeXnKDSrvxGL7j5EvOUYYAG1WEvZLzNptImWFoAZFF7
|
||||
h9+HmyZGWiEsCaDrunGNCJpwtborMkH8om6usa3SNaAdM9eKVzrX6yEc+AN3FcoY
|
||||
/HQxz9rV7b3E4xjVoAkJRyuzihb0ITyYabFYuLI6u4UIlOEhf0SCr7W4KCKepuwS
|
||||
Lg2MzVRiiuIRgZUqIzI8Oi5ta51mDYoaPxCz1bHiNCKvXqKdAMj6EePFtEkYgw2k
|
||||
5lMCAwEAAaOCA0QwggNAMAwGA1UdEwEB/wQCMAAwKQYDVR0lBCIwIAYIKwYBBQUH
|
||||
AwEGCCsGAQUFBwMCBgpghkgBhvhNAQIDMA4GA1UdDwEB/wQEAwIFoDA2BgNVHR8E
|
||||
LzAtMCugKaAnhiVodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkaWcyczItMzQuY3Js
|
||||
MF0GA1UdIARWMFQwSAYLYIZIAYb9bQEHFwIwOTA3BggrBgEFBQcCARYraHR0cDov
|
||||
L2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzAIBgZngQwBAgIw
|
||||
dgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5
|
||||
LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
|
||||
b20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAUQMK9J47MNIMwojPX
|
||||
+2yz8LQsgM4wIwYDVR0RBBwwGoIMKi5rb21lY3QuY29tggprb21lY3QuY29tMB0G
|
||||
A1UdDgQWBBQFlcp3bINcQRB28YU7+JkTZNny0jCCAX8GCisGAQQB1nkCBAIEggFv
|
||||
BIIBawFpAHYA7s3QZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGImfrM
|
||||
PQAABAMARzBFAiEAwa+pHvLsodr6zaIJHpuep/5KHQtFWdq5xjPxkRYimQACICag
|
||||
BJw5onUWGDUuw4VDmO1baenKnAG+KdDcDHBdnySIAHYASLDja9qmRzQP5WoC+p0w
|
||||
6xxSActW3SyB2bu/qznYhHMAAAGImfrNEQAABAMARzBFAiEAv+fe4tG+BSqZ3yeT
|
||||
NbBDVtfvEMqxrTmAffGO+qT8Zr8CIAIjfZVueI2UAZdrShrRlzZZLK2Npd/t0i6o
|
||||
4BIaw1o5AHcA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGImfrN
|
||||
dAAABAMASDBGAiEA73dx8CnNv0WGtgByp+Uz3dLspndGI3hu1NOvMtjCCxMCIQD7
|
||||
BoJJe9knyxpvEOPY+O5ybWj/0HIirHxwJu+qpwp6ZzANBgkqhkiG9w0BAQsFAAOC
|
||||
AQEABTskU6npLQQx5MUhAhoxH+nu+nz42E3A1vqljjHSey25QLtYKZG+7Zy4g9rZ
|
||||
Lu09+/byhUL4VSYXaVbuxkwCu2DRnDH34C31Ons3JN5biE/kAqaXA0e+84sUGoot
|
||||
UtDTe11F1bWwPO3/WYXICGO+GaukUwI4EZP69n6aROMS4+bXiYDqVqbcjq2v9yoq
|
||||
JoOAkQOSg9fEYkz/oO/xqkTEK1uNjWErWiDW3vuWaXfya2lyRQYasfuryKSNBzhJ
|
||||
W9tqNooO7Y1kbVSRrZ44kWyBWn0bVQGKzmHeckFP7rkYQi/g34UorHvMUUcJkaLE
|
||||
p3lPKExQ4l0G4+CNqI2ZawgBrg==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
|
||||
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
|
||||
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
|
||||
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3
|
||||
MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
|
||||
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE
|
||||
CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD
|
||||
EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD
|
||||
BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv
|
||||
K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e
|
||||
cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY
|
||||
pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n
|
||||
eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB
|
||||
AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
|
||||
HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv
|
||||
9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v
|
||||
b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n
|
||||
b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG
|
||||
CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz
|
||||
91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2
|
||||
RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi
|
||||
DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11
|
||||
GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x
|
||||
LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT
|
||||
MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv
|
||||
IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx
|
||||
MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
|
||||
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku
|
||||
Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1
|
||||
dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi
|
||||
CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H
|
||||
Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/
|
||||
3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+
|
||||
6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI
|
||||
gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E
|
||||
GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud
|
||||
IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr
|
||||
BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al
|
||||
oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9
|
||||
MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv
|
||||
bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d
|
||||
H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg
|
||||
OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq
|
||||
9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO
|
||||
KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3
|
||||
qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm
|
||||
rw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
|
||||
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
|
||||
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
|
||||
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
|
||||
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
|
||||
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
|
||||
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
|
||||
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
|
||||
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
|
||||
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
|
||||
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
|
||||
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
|
||||
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
|
||||
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
|
||||
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
|
||||
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
|
||||
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
|
||||
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
|
||||
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
|
||||
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
|
||||
ReYNnyicsbkqWletNw+vHX/bvZ8=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4EN34fKbxwJ+z
|
||||
QpGcSatVcoDPA1ke6gmUueWzKmqnHhXa5cvmwfvNFin3XV53A9aVCkO+0jbBGcgt
|
||||
Q0/hIpjq6PBiE1Zf4rmXOkLQzP2Xl5yg0q78Ri+4+RLzlGGABtVhL2S8zabSJlha
|
||||
AGRRe4ffh5smRlohLAmg67pxjQiacLW6KzJB/KJurrGt0jWgHTPXilc61+shHPgD
|
||||
dxXKGPx0Mc/a1e29xOMY1aAJCUcrs4oW9CE8mGmxWLiyOruFCJThIX9Egq+1uCgi
|
||||
nqbsEi4NjM1UYoriEYGVKiMyPDoubWudZg2KGj8Qs9Wx4jQir16inQDI+hHjxbRJ
|
||||
GIMNpOZTAgMBAAECggEBAJtIl4r/1nOTdudrXJ6GRAYlQGfkwjXjacvP/Onm+e0c
|
||||
44E1Zoy50G1XqnXmjkBHu6sm6ro8bDcCQi91Xxlm760WcV28RJ1GEB5151Jx7esK
|
||||
2/eNZlSr/azGbGeUIaE5oqCHtCvYL0mRUe4z8G4RkjJRG+Hxbi4YEdNxq2wKeFyZ
|
||||
EqZXBPfw259tY5lIZn3lE+3IuDJw9LDOVT/xq/ZFHgULbPYEBOj8tp/BbF6JOrjl
|
||||
CPOkjdRIM8ompztlxBce3biVXVFP22dH9D5221Cj3sYc79LkONOjaKWklsGCjbNO
|
||||
UCcZJZ70hZpdJCUBN2CMJcolBH+xT5B+kPnyj2pRQlECgYEA9UlbXTmGAyEacJVp
|
||||
FfwVEIVjIJOxm5XZ7uI0/06MURviMDfVsOdXrswF6GcoJo1VT88Cmz1zn1/olPEW
|
||||
Zardwch/8TXbA5+hUXEUN68h9mfZucliewZePX5uPN5+WiaClZ5WQjUTpjR1IFGk
|
||||
Y3wn55B15ZKZyw7EPtulnpcvYokCgYEAwBr6espToQ57rU4Vh92T/pSuhumPZJIm
|
||||
yVVhf+iEQT9Y9BSfM9reYxhwVZQVTdryQaFz0yQ1XIxG2tn6edfpnjUy+NAgsrdT
|
||||
WAgzDKru0l7ht3/sr5By6yWRbyUYcPBV6FSAbiFKrV467YovVtcCfQdVNNUt8e7t
|
||||
/ufQS8zqevsCgYEAkAnc2hjOhoXo9dX3WM6oPARoWpgAgyHzUWGKx6YDphmesLwJ
|
||||
A5JGnkH28iupm0IBqBUjLbBfdmamuNf+VAOLp6Eq6KW8kBssaxvhSHXSltUTORN2
|
||||
flIWAzx8Vcg+IIhexKevdb+fY0mIwkrPIxCkikn9wateHqz0Nwla749OZykCgYAc
|
||||
O9rUcSgZY6eJsRA5B7fYksGT0n/gqBpLPOE3i1Tkwgqw1NcRJ/nHVrAr47e92ZAB
|
||||
VVlQjuHI2FURlTfa8IDFX8w+BVjI62i0Z4AZPIYdJRTHg2Wl5/T72mmljC4rayc1
|
||||
HjZB+WKgWFkQ0F5kxPT4qzs6qJo4FIWmESvr+BH+QQKBgGJ+ZT90jsERQfMzv6aL
|
||||
OW8huYImT0NvRKqIG0K14amm1ku0G+rL8HMy0JIJUs0x5BqwacUEBHffQkAPQOIh
|
||||
/6XBAsiZD10QlomuDMl1sOQSKacIOFlH8KFPM0RdgCRQk5oiYmdh2CeavkjkE9Cp
|
||||
HpC22rgeJoxV9fq5Zd2diWJh
|
||||
-----END PRIVATE KEY-----
|
Binary file not shown.
|
@ -144,6 +144,7 @@ public class HttpClientUtilsTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("GET 成功")
|
||||
public void get_Success() throws IOException {
|
||||
|
|
|
@ -48,6 +48,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
*/
|
||||
@SpringBootTest
|
||||
@DisplayName("ProtocolJsonUtils 测试类")
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ProtocolJsonUtilsTest {
|
||||
|
||||
private ProtocolResp protocolResp;
|
||||
|
|
|
@ -1,122 +1,146 @@
|
|||
package com.cmcc.magent.service.impl;
|
||||
|
||||
import com.cmcc.magent.config.PlatformServiceConfig;
|
||||
import com.cmcc.magent.misc.HttpClientUtils;
|
||||
import com.cmcc.magent.misc.JsonUtils;
|
||||
import com.cmcc.hy.gzs.common.result.Result;
|
||||
import com.cmcc.magent.pojo.po.RegisterAgent;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import com.cmcc.magent.service.PlatformApiFeignClientService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.slf4j.Logger;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 单元测试类 {@code PlatformApiServiceImplTest} 用于测试 {@link PlatformApiServiceImpl} 的功能。
|
||||
* PlatformApiServiceImplTest 类用于测试 {@link PlatformApiServiceImpl} 的功能。
|
||||
* <p>
|
||||
* 测试的主要目标是确保 {@link PlatformApiServiceImpl#registerAgent(RegisterAgent)} 方法能够正常工作,
|
||||
* 该测试类包含多个单元测试,验证与 {@link PlatformApiFeignClientService} 相关的方法的正确性。
|
||||
* </p>
|
||||
*
|
||||
* <p>测试中使用了 {@code MockWebServer} 来模拟 HTTP 请求和响应,避免依赖实际的外部服务。</p>
|
||||
*
|
||||
* <p>主要验证内容包括:</p>
|
||||
* <ul>
|
||||
* <li>是否正确构造了 HTTP 请求(如方法和路径)。</li>
|
||||
* <li>是否正确处理了 HTTP 响应并返回预期结果。</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>依赖注入说明:</p>
|
||||
* <ul>
|
||||
* <li>通过 {@code @Resource} 注入被测试的 {@code PlatformApiServiceImpl}。</li>
|
||||
* <li>通过 {@code @Autowired} 注入 {@code WebClient.Builder},用于生成测试时专用的 {@code WebClient}。</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author huangxin@cmhi.chinamobile.com
|
||||
* @version 1.0.0
|
||||
* @since 2025-01-14
|
||||
* @since 2025-03-07
|
||||
*/
|
||||
@SpringBootTest
|
||||
@DisplayName("平台服务接口")
|
||||
@DisplayName("平台访问接口测试")
|
||||
public class PlatformApiServiceImplTest {
|
||||
|
||||
/**
|
||||
* 被测试的服务类 {@link PlatformApiServiceImpl}。
|
||||
*/
|
||||
@Resource
|
||||
@Mock
|
||||
private PlatformApiFeignClientService platformApiServiceFeign;
|
||||
|
||||
@InjectMocks
|
||||
private PlatformApiServiceImpl platformApiService;
|
||||
|
||||
@Resource
|
||||
private PlatformServiceConfig platformServiceConfig;
|
||||
|
||||
private MockedStatic<HttpClientUtils> platformMock;
|
||||
|
||||
private MockedStatic<JsonUtils> jsonMock;
|
||||
private Logger logger;
|
||||
|
||||
/**
|
||||
* 在每个测试前进行设置。
|
||||
* 创建 HttpClient 和响应的 Mock 对象,并初始化 Mockito。
|
||||
*
|
||||
* 在每个测试之前初始化 Mockito 注解。
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
platformMock = mockStatic(HttpClientUtils.class, Mockito.CALLS_REAL_METHODS);
|
||||
jsonMock = mockStatic(JsonUtils.class);
|
||||
|
||||
logger = mock(Logger.class);
|
||||
|
||||
// 获取 MyService 的 Class 对象
|
||||
Class<?> clazz = PlatformApiServiceImpl.class;
|
||||
// 获取 log 字段
|
||||
Field logField = clazz.getDeclaredField("log");
|
||||
// 设置字段可访问
|
||||
logField.setAccessible(true);
|
||||
// 获取 Unsafe 实例
|
||||
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
// 获取 log 字段的偏移量
|
||||
long offset = unsafe.staticFieldOffset(logField);
|
||||
// 获取 log 字段所属的类对象
|
||||
Object base = unsafe.staticFieldBase(logField);
|
||||
|
||||
// 使用 Unsafe 修改 log 字段的值
|
||||
unsafe.putObject(base, offset, logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在每个测试后清理资源。
|
||||
*/
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
platformMock.close();
|
||||
jsonMock.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 {@link PlatformApiServiceImpl#registerAgent(RegisterAgent)} 方法。
|
||||
*
|
||||
* <p>验证以下内容:</p>
|
||||
* <ul>
|
||||
* <li>是否正确发送了 HTTP POST 请求到指定路径(如 {@code /register})。</li>
|
||||
* <li>是否正确处理了 HTTP 响应并返回预期的结果。</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>测试流程:</p>
|
||||
* <ol>
|
||||
* <li>设置 MockWebServer 的响应内容为 {@code {"message": "Hello, World!"}}。</li>
|
||||
* <li>使用测试数据(如 {@link RegisterAgent} 对象)调用 {@code registerAgent} 方法。</li>
|
||||
* <li>验证返回值是否等于设置的响应内容。</li>
|
||||
* <li>验证发送的请求是否符合预期(如方法为 POST,路径为 /register)。</li>
|
||||
* </ol>
|
||||
* 测试在成功执行情况下,调用 responseDeploymentResult 方法返回结果。
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@DisplayName("设备注册接口测试")
|
||||
void testFetchData() throws IOException {
|
||||
// 准备模拟的 HTTP 响应
|
||||
String mockResponse = "Mocked Response";
|
||||
@DisplayName("部署结果响应成功")
|
||||
public void responseDeploymentResult_SuccessfulExecution_ReturnsResult() {
|
||||
String deploymentId = "12345";
|
||||
Integer status = 1;
|
||||
Result<String> expectedResponse = Result.success("Deployment updated successfully");
|
||||
|
||||
final RegisterAgent agent = RegisterAgent.builder().deviceId("123542535").build();
|
||||
when(platformApiServiceFeign.responseDeploymentResultFeign(deploymentId, status)).thenReturn(expectedResponse);
|
||||
|
||||
jsonMock.when(() -> JsonUtils.getJson(any(Object.class))).thenReturn(mockResponse);
|
||||
Result<String> actualResponse = platformApiService.responseDeploymentResult(deploymentId, status);
|
||||
|
||||
platformMock.when(() -> HttpClientUtils.postJson(platformServiceConfig + "/register", null, mockResponse, null)).thenReturn(
|
||||
"Mocked Response");
|
||||
assertNotNull(actualResponse);
|
||||
assertEquals(expectedResponse, actualResponse);
|
||||
}
|
||||
|
||||
// 调用被测试方法
|
||||
final String result = platformApiService.registerAgent(agent);
|
||||
/**
|
||||
* 测试在调用 responseDeploymentResult 方法时抛出异常,返回 null。
|
||||
*
|
||||
* @throws RuntimeException 可能抛出的异常
|
||||
*/
|
||||
@Test
|
||||
@DisplayName("部署结果响应异常")
|
||||
public void responseDeploymentResult_ExceptionThrown_ReturnsNull() {
|
||||
String deploymentId = "12345";
|
||||
Integer status = 1;
|
||||
Exception e = new RuntimeException("Service exception");
|
||||
|
||||
// 验证结果
|
||||
assertThat(result).isEqualTo(mockResponse);
|
||||
when(platformApiServiceFeign.responseDeploymentResultFeign(deploymentId, status)).thenThrow(e);
|
||||
|
||||
Result<String> ret = platformApiService.responseDeploymentResult(deploymentId, status);
|
||||
|
||||
assertNull(ret);
|
||||
verify(logger).error(eq("Response deployment {} result exception: {}"), eq("12345"), eq(e.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试在成功注册情况下,调用 registerAgent 方法返回成功结果。
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@DisplayName("注册代理成功")
|
||||
public void registerAgent_SuccessfulRegistration_ReturnsSuccessResult() {
|
||||
RegisterAgent agent = new RegisterAgent("1234567890");
|
||||
Result<String> expected = Result.success("Registration successful");
|
||||
when(platformApiServiceFeign.registerAgentFeign(agent)).thenReturn(expected);
|
||||
|
||||
Result<String> actual = platformApiService.registerAgent(agent);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试在调用 registerAgent 方法时抛出异常,返回 null。
|
||||
*
|
||||
* @throws RuntimeException 可能抛出的异常
|
||||
*/
|
||||
@Test
|
||||
@DisplayName("注册代理异常")
|
||||
public void registerAgent_ExceptionThrown_ReturnsNull() {
|
||||
RegisterAgent agent = new RegisterAgent("1234567890");
|
||||
Exception e = new RuntimeException("Registration failedxxxx");
|
||||
when(platformApiServiceFeign.registerAgentFeign(agent)).thenThrow(e);
|
||||
|
||||
Result<String> ret = platformApiService.registerAgent(agent);
|
||||
|
||||
assertNull(ret);
|
||||
verify(logger).error(eq("Register agent client {} exception: {}"), eq("1234567890"), eq(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ public class ResourceUsageServiceImplTest {
|
|||
|
||||
resourceUsageService.performTask();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
CircularQueue<ResourceUsage> resourceUsageQueue = (CircularQueue<ResourceUsage>) ReflectionTestUtils.getField(resourceUsageService,
|
||||
"resourceUsageQueue");
|
||||
assertNotNull(resourceUsageQueue, "Resource usage queue should not be null");
|
||||
|
@ -109,6 +110,7 @@ public class ResourceUsageServiceImplTest {
|
|||
|
||||
resourceUsageService.performTask();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
CircularQueue<ResourceUsage> resourceUsageQueue = (CircularQueue<ResourceUsage>) ReflectionTestUtils.getField(resourceUsageService,
|
||||
"resourceUsageQueue");
|
||||
|
||||
|
@ -137,6 +139,7 @@ public class ResourceUsageServiceImplTest {
|
|||
|
||||
resourceUsageService.performTask();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
CircularQueue<ResourceUsage> resourceUsageQueue = (CircularQueue<ResourceUsage>) ReflectionTestUtils.getField(resourceUsageService,
|
||||
"resourceUsageQueue");
|
||||
assertNotNull(resourceUsageQueue, "Resource usage queue should not be null");
|
||||
|
|
|
@ -59,7 +59,7 @@ protocol.crypto-type=0
|
|||
|
||||
# Platform Service
|
||||
# Manager Platform URL
|
||||
service.platform-url=http://xajhuang.com:1300
|
||||
service.platform-url=http://xajhuang.com:3006/post
|
||||
# APPID
|
||||
service.platform-appid=appid
|
||||
# cluster name
|
||||
|
@ -73,3 +73,5 @@ thread.max-pool-size=10
|
|||
thread.queue-capacity=25
|
||||
thread.name-prefix=Async-
|
||||
|
||||
gzs.sign.client-details-enabled=true
|
||||
gzs.sign.client-details.'mw-open-82hsbmz8'=98rnk8pz6j08fp6q
|
Loading…
Reference in New Issue