feat(接口测试): 支持服务端调试更新环境变量
This commit is contained in:
parent
74fb26bd1d
commit
7ae3ea52fb
|
@ -1,7 +1,9 @@
|
||||||
package io.metersphere.api.listener;
|
package io.metersphere.api.listener;
|
||||||
|
|
||||||
|
import io.metersphere.api.service.ApiEnvironmentService;
|
||||||
import io.metersphere.sdk.constants.KafkaTopicConstants;
|
import io.metersphere.sdk.constants.KafkaTopicConstants;
|
||||||
import io.metersphere.sdk.dto.SocketMsgDTO;
|
import io.metersphere.sdk.dto.SocketMsgDTO;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.sdk.util.LogUtils;
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
import io.metersphere.sdk.util.WebSocketUtils;
|
import io.metersphere.sdk.util.WebSocketUtils;
|
||||||
|
@ -10,6 +12,8 @@ import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
import org.springframework.kafka.annotation.KafkaListener;
|
import org.springframework.kafka.annotation.KafkaListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 后端调试消息监听器
|
* 后端调试消息监听器
|
||||||
*/
|
*/
|
||||||
|
@ -17,13 +21,25 @@ import org.springframework.stereotype.Component;
|
||||||
public class DebugListener {
|
public class DebugListener {
|
||||||
public static final String DEBUG_CONSUME_ID = "MS-API-DEBUG-CONSUME";
|
public static final String DEBUG_CONSUME_ID = "MS-API-DEBUG-CONSUME";
|
||||||
|
|
||||||
|
private ApiEnvironmentService apiEnvironmentService;
|
||||||
|
;
|
||||||
|
|
||||||
@KafkaListener(id = DEBUG_CONSUME_ID, topics = KafkaTopicConstants.API_REPORT_DEBUG_TOPIC, groupId = DEBUG_CONSUME_ID + "_" + "${random.uuid}")
|
@KafkaListener(id = DEBUG_CONSUME_ID, topics = KafkaTopicConstants.API_REPORT_DEBUG_TOPIC, groupId = DEBUG_CONSUME_ID + "_" + "${random.uuid}")
|
||||||
public void debugConsume(ConsumerRecord<?, String> record) {
|
public void debugConsume(ConsumerRecord<?, String> record) {
|
||||||
try {
|
try {
|
||||||
|
if (apiEnvironmentService == null) {
|
||||||
|
apiEnvironmentService = CommonBeanFactory.getBean(ApiEnvironmentService.class);
|
||||||
|
}
|
||||||
LogUtils.info("接收到执行结果:{}", record.key());
|
LogUtils.info("接收到执行结果:{}", record.key());
|
||||||
if (ObjectUtils.isNotEmpty(record.value()) && WebSocketUtils.has(record.key().toString())) {
|
if (ObjectUtils.isNotEmpty(record.value()) && WebSocketUtils.has(record.key().toString())) {
|
||||||
SocketMsgDTO dto = JSON.parseObject(record.value(), SocketMsgDTO.class);
|
SocketMsgDTO dto = JSON.parseObject(record.value(), SocketMsgDTO.class);
|
||||||
|
|
||||||
|
// 处理环境变量
|
||||||
|
if (dto.getTaskResult() instanceof List environmentVariables) {
|
||||||
|
LogUtils.info("{} 处理环境变量", record.key());
|
||||||
|
apiEnvironmentService.parseEnvironment(environmentVariables);
|
||||||
|
}
|
||||||
|
|
||||||
LogUtils.info("{} 推送执行结果类型【 {} 】", record.key(), dto.getMsgType());
|
LogUtils.info("{} 推送执行结果类型【 {} 】", record.key(), dto.getMsgType());
|
||||||
WebSocketUtils.sendMessageSingle(dto);
|
WebSocketUtils.sendMessageSingle(dto);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import io.metersphere.sdk.domain.EnvironmentBlob;
|
||||||
|
import io.metersphere.sdk.mapper.EnvironmentBlobMapper;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApiEnvironmentService {
|
||||||
|
|
||||||
|
private static final String COMMON_CONFIG = "config";
|
||||||
|
private static final String VARIABLES = "commonVariables";
|
||||||
|
private static final String VALUE = "value";
|
||||||
|
private static final String ENABLE = "enable";
|
||||||
|
private static final String NAME = "key";
|
||||||
|
private static final String ENV_STR = "MS.ENV.";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private EnvironmentBlobMapper environmentBlobMapper;
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public void parseEnvironment(List<String> environmentVariables) {
|
||||||
|
try {
|
||||||
|
environmentVariables.forEach(this::parseEvn);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseEvn(String envStr) {
|
||||||
|
String[] envStringArr = envStr.split(StringUtils.LF);
|
||||||
|
Map<String, Map<String, String>> envVarsMap = new HashMap<>();
|
||||||
|
for (String env : envStringArr) {
|
||||||
|
if (StringUtils.contains(env, "=")) {
|
||||||
|
String[] envItem = env.split("=");
|
||||||
|
if (envItem.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String jmeterVarKey = envItem[0];
|
||||||
|
if (checkValidity(jmeterVarKey)) {
|
||||||
|
String[] envAndKeyArr = jmeterVarKey.substring(ENV_STR.length()).split("\\.");
|
||||||
|
if (envAndKeyArr.length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String envId = envAndKeyArr[0];
|
||||||
|
String key = StringUtils.join(ArrayUtils.remove(envAndKeyArr, 0), ".");
|
||||||
|
String value = StringUtils.substring(env, jmeterVarKey.length() + 1);
|
||||||
|
if (StringUtils.isNoneEmpty(envId, key)) {
|
||||||
|
envVarsMap.computeIfAbsent(envId, k -> new HashMap<>()).put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!envVarsMap.isEmpty()) {
|
||||||
|
envVarsMap.forEach(this::addParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkValidity(String str) {
|
||||||
|
return str != null && str.startsWith(ApiEnvironmentService.ENV_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addParam(String environmentId, Map<String, String> varMap) {
|
||||||
|
if (varMap.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EnvironmentBlob environment = environmentBlobMapper.selectByPrimaryKey(environmentId);
|
||||||
|
if (environment == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JsonNode configObj = objectMapper.readTree(new String(environment.getConfig(), StandardCharsets.UTF_8));
|
||||||
|
if (configObj.isMissingNode() || !configObj.has(VARIABLES)) {
|
||||||
|
ObjectNode newCommonConfig = objectMapper.createObjectNode();
|
||||||
|
List<JsonNode> variables = createArray(varMap);
|
||||||
|
newCommonConfig.putArray(VARIABLES).addAll(variables);
|
||||||
|
((ObjectNode) configObj).set(COMMON_CONFIG, newCommonConfig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode variables = configObj.path(VARIABLES);
|
||||||
|
if (variables.isMissingNode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean envNeedUpdate = false;
|
||||||
|
for (Map.Entry<String, String> entry : varMap.entrySet()) {
|
||||||
|
boolean contains = false;
|
||||||
|
Iterator<JsonNode> elements = variables.elements();
|
||||||
|
int length = 0;
|
||||||
|
while (elements.hasNext()) {
|
||||||
|
length++;
|
||||||
|
JsonNode jsonObj = elements.next();
|
||||||
|
if (jsonObj.has(NAME) && jsonObj.has(VALUE)
|
||||||
|
&& jsonObj.get(NAME).asText().equals(entry.getKey())) {
|
||||||
|
if (jsonObj.get(VALUE).asText().equals(entry.getValue())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
((ObjectNode) jsonObj).put(VALUE, entry.getValue());
|
||||||
|
envNeedUpdate = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
contains = true;
|
||||||
|
envNeedUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contains) {
|
||||||
|
ObjectNode itemObj = objectMapper.createObjectNode();
|
||||||
|
itemObj.put(NAME, entry.getKey());
|
||||||
|
itemObj.put(VALUE, entry.getValue());
|
||||||
|
itemObj.put(ENABLE, true);
|
||||||
|
((ArrayNode) variables).set(length - 1, itemObj);
|
||||||
|
((ObjectNode) configObj).set(VARIABLES, variables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (envNeedUpdate) {
|
||||||
|
environment.setConfig(objectMapper.writeValueAsBytes(configObj));
|
||||||
|
environmentBlobMapper.updateByPrimaryKeyWithBLOBs(environment);
|
||||||
|
}
|
||||||
|
} catch (JsonProcessingException ex) {
|
||||||
|
LogUtils.error("Setting environment variables exception", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<JsonNode> createArray(Map<String, String> varMap) {
|
||||||
|
return varMap.entrySet().stream()
|
||||||
|
.map(entry -> objectMapper.createObjectNode()
|
||||||
|
.put(NAME, entry.getKey())
|
||||||
|
.put(VALUE, entry.getValue())
|
||||||
|
.put(ENABLE, true))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue