diff --git a/arex-storage-config/pom.xml b/arex-storage-config/pom.xml
index 56bfeae4..5eb16992 100644
--- a/arex-storage-config/pom.xml
+++ b/arex-storage-config/pom.xml
@@ -45,7 +45,7 @@
arex-storage-service
com.arextest
- 1.0.48
+ 1.0.49
diff --git a/arex-storage-model/pom.xml b/arex-storage-model/pom.xml
index 3cf86e94..3f457b96 100644
--- a/arex-storage-model/pom.xml
+++ b/arex-storage-model/pom.xml
@@ -7,7 +7,7 @@
arex-storage-service
com.arextest
- 1.0.48
+ 1.0.49
diff --git a/arex-storage-model/src/main/java/com/arextest/model/replay/QueryReplayResultResponseType.java b/arex-storage-model/src/main/java/com/arextest/model/replay/QueryReplayResultResponseType.java
index 496695d0..32f0ece2 100644
--- a/arex-storage-model/src/main/java/com/arextest/model/replay/QueryReplayResultResponseType.java
+++ b/arex-storage-model/src/main/java/com/arextest/model/replay/QueryReplayResultResponseType.java
@@ -14,4 +14,5 @@ public class QueryReplayResultResponseType implements Response {
private ResponseStatusType responseStatusType;
private List resultHolderList;
+ private Boolean invalidResult;
}
\ No newline at end of file
diff --git a/arex-storage-web-api/pom.xml b/arex-storage-web-api/pom.xml
index 5d172c3b..7f1c0c97 100644
--- a/arex-storage-web-api/pom.xml
+++ b/arex-storage-web-api/pom.xml
@@ -123,7 +123,7 @@
arex-storage-service
com.arextest
- 1.0.48
+ 1.0.49
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/beans/StorageAutoConfiguration.java b/arex-storage-web-api/src/main/java/com/arextest/storage/beans/StorageAutoConfiguration.java
index f2f64f63..935df69c 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/beans/StorageAutoConfiguration.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/beans/StorageAutoConfiguration.java
@@ -22,6 +22,7 @@
import com.arextest.storage.service.AgentWorkingListener;
import com.arextest.storage.service.AgentWorkingService;
import com.arextest.storage.service.AutoDiscoveryEntryPointListener;
+import com.arextest.storage.service.InvalidReplayCaseService;
import com.arextest.storage.service.MockSourceEditionService;
import com.arextest.storage.service.PrepareMockResultService;
import com.arextest.storage.service.ScheduleReplayingService;
@@ -151,8 +152,9 @@ public AgentWorkingService agentWorkingService(MockResultProvider mockResultProv
public AgentWorkingMetricService agentWorkingMetricService(
AgentWorkingService agentWorkingService,
MockSourceEditionService editableService,
- List metricListeners) {
- return new AgentWorkingMetricService(agentWorkingService, editableService, metricListeners);
+ List metricListeners,
+ InvalidReplayCaseService invalidReplayCaseService) {
+ return new AgentWorkingMetricService(agentWorkingService, editableService, metricListeners, invalidReplayCaseService);
}
@Bean
@@ -166,8 +168,10 @@ public MatchStrategyMetricService matchStrategyMetricService(
@ConditionalOnMissingBean(ScheduleReplayQueryController.class)
public ScheduleReplayQueryController scheduleReplayQueryController(
ScheduleReplayingService scheduleReplayingService,
- PrepareMockResultService prepareMockResultService) {
- return new ScheduleReplayQueryController(scheduleReplayingService, prepareMockResultService);
+ PrepareMockResultService prepareMockResultService,
+ InvalidReplayCaseService invalidReplayCaseService) {
+ return new ScheduleReplayQueryController(scheduleReplayingService, prepareMockResultService,
+ invalidReplayCaseService);
}
@Bean
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWepServiceApiClient.java b/arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWebServiceApiClient.java
similarity index 99%
rename from arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWepServiceApiClient.java
rename to arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWebServiceApiClient.java
index 01536292..f47567b0 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWepServiceApiClient.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/client/HttpWebServiceApiClient.java
@@ -35,7 +35,7 @@
*/
@Component
@Slf4j
-public final class HttpWepServiceApiClient {
+public final class HttpWebServiceApiClient {
private final static int TEN_SECONDS_TIMEOUT = 10_000;
private RestTemplate restTemplate;
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/metric/AgentWorkingMetricService.java b/arex-storage-web-api/src/main/java/com/arextest/storage/metric/AgentWorkingMetricService.java
index 87372ef7..0fcf18fc 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/metric/AgentWorkingMetricService.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/metric/AgentWorkingMetricService.java
@@ -12,9 +12,12 @@
import java.util.concurrent.TimeUnit;
import javax.validation.constraints.NotNull;
+import com.arextest.storage.service.InvalidReplayCaseService;
import com.arextest.storage.service.MockSourceEditionService;
+import com.arextest.storage.trace.MDCTracer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
/**
* created by xinyuan_wang on 2023/6/7
@@ -31,15 +34,19 @@ public class AgentWorkingMetricService {
private static final String REASON = "reason";
private static final String INVALID_CASE_METHOD_NAME = "invalidCase";
+ private static final String INVALID_REPLAY_CASE_METHOD_NAME = "invalidReplayCase";
public final List metricListeners;
private final AgentWorkingService agentWorkingService;
private final MockSourceEditionService editableService;
+ private final InvalidReplayCaseService invalidReplayCaseService;
+
public AgentWorkingMetricService(AgentWorkingService agentWorkingService,
MockSourceEditionService editableService,
- List metricListeners) {
+ List metricListeners, InvalidReplayCaseService invalidReplayCaseService) {
this.agentWorkingService = agentWorkingService;
this.editableService = editableService;
this.metricListeners = metricListeners;
+ this.invalidReplayCaseService = invalidReplayCaseService;
}
private static long nanosToMillis(long duration) {
@@ -74,6 +81,12 @@ public byte[] queryMockResult(@NotNull T recordItem,
}
public void invalidCase(InvalidCaseRequest requestType) {
+ // replayId is not empty, means this is a replay case
+ if (StringUtils.isNotEmpty(requestType.getReplayId())) {
+ invalidReplayCase(requestType);
+ return;
+ }
+ // recordId is not empty, means this is a record case
editableService.invalidCase(ProviderNames.DEFAULT, requestType.getRecordId());
if (CollectionUtils.isEmpty(metricListeners)) {
return;
@@ -99,4 +112,25 @@ private void recordEntryTime(String path, AREXMocker item, long timeMillis) {
}
}
+ private void invalidReplayCase(InvalidCaseRequest request) {
+ // save into redis
+ String replayId = request.getReplayId();
+ MDCTracer.addReplayId(replayId);
+ invalidReplayCaseService.saveInvalidCase(replayId);
+ LOGGER.info("[[title=invalidReplayCase]]invalid replayId:{}", replayId);
+ MDCTracer.clear();
+ // metric
+ if (CollectionUtils.isEmpty(metricListeners)) {
+ return;
+ }
+ Map tags = new HashMap<>(3);
+ tags.put(CLIENT_APP_ID, request.getAppId());
+ tags.put(PATH, INVALID_REPLAY_CASE_METHOD_NAME);
+ tags.put(REASON, request.getReason());
+
+ for (MetricListener metricListener : metricListeners) {
+ metricListener.recordMatchingCount(METRIC_NAME, tags);
+ }
+ }
+
}
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/model/InvalidCaseRequest.java b/arex-storage-web-api/src/main/java/com/arextest/storage/model/InvalidCaseRequest.java
index 48336051..e9a2ae6a 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/model/InvalidCaseRequest.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/model/InvalidCaseRequest.java
@@ -15,6 +15,11 @@ public class InvalidCaseRequest {
* FastReject or QueueOverFlow
*/
private String reason;
+ /**
+ * Replay id
+ * replay scene must be not null
+ */
+ private String replayId;
@Override
public String toString() {
@@ -22,6 +27,7 @@ public String toString() {
"appId='" + appId + '\'' +
", recordId='" + recordId + '\'' +
", reason=" + reason +
+ ", replayId='" + replayId + '\'' +
'}';
}
}
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/service/InvalidReplayCaseService.java b/arex-storage-web-api/src/main/java/com/arextest/storage/service/InvalidReplayCaseService.java
new file mode 100644
index 00000000..67d4ddf7
--- /dev/null
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/service/InvalidReplayCaseService.java
@@ -0,0 +1,45 @@
+package com.arextest.storage.service;
+
+import com.arextest.common.cache.CacheProvider;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * listen agent service query storage service if exception mark replay case invalid
+ * @author: sldu
+ * @date: 2023/12/6 13:46
+ **/
+@Component
+@Slf4j
+public class InvalidReplayCaseService {
+ @Resource
+ private CacheProvider redisCacheProvider;
+ private static final byte[] INVALID_CASE_KEY = "invalid_case".getBytes(StandardCharsets.UTF_8);
+ private static final byte[] INVALID_CASE_VALUE = "1".getBytes(StandardCharsets.UTF_8);
+ private static final long THREE_MINUTES_EXPIRE = 3 * 60L;
+
+ public void saveInvalidCase(String replayId) {
+ byte[] key = toInvalidCaseKeyBytes(replayId);
+ redisCacheProvider.put(key, THREE_MINUTES_EXPIRE, INVALID_CASE_VALUE);
+ }
+ public boolean isInvalidCase(String replayId) {
+ byte[] key = toInvalidCaseKeyBytes(replayId);
+ try {
+ byte[] bytes = redisCacheProvider.get(key);
+ if (bytes != null) {
+ return true;
+ }
+ } catch (Exception e) {
+ LOGGER.error("isInvalidCase error", e);
+ }
+ return false;
+ }
+ private byte[] toInvalidCaseKeyBytes(String replayId) {
+ byte[] paramKey = replayId.getBytes(StandardCharsets.UTF_8);
+ return ByteBuffer.allocate(INVALID_CASE_KEY.length + paramKey.length).put(INVALID_CASE_KEY).put(paramKey).array();
+ }
+}
\ No newline at end of file
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/service/MockSourceEditionService.java b/arex-storage-web-api/src/main/java/com/arextest/storage/service/MockSourceEditionService.java
index 8bea71af..f326518b 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/service/MockSourceEditionService.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/service/MockSourceEditionService.java
@@ -7,9 +7,11 @@
import com.arextest.storage.repository.RepositoryProviderFactory;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -52,9 +54,12 @@ public boolean removeAll(String providerName, String recordId) {
return false;
}
Set categoryTypes = providerFactory.getCategoryTypes();
+ Map removeResults = new HashMap<>(categoryTypes.size());
for (MockCategoryType categoryType : categoryTypes) {
- repositoryWriter.removeBy(categoryType, recordId);
+ long removeResult = repositoryWriter.removeBy(categoryType, recordId);
+ removeResults.put(categoryType.getName(), removeResult > 0);
}
+ LOGGER.info("remove all record result:{} for recordId:{}", removeResults, recordId);
return true;
}
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/service/QueryConfigService.java b/arex-storage-web-api/src/main/java/com/arextest/storage/service/QueryConfigService.java
index 47ceff86..14c41297 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/service/QueryConfigService.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/service/QueryConfigService.java
@@ -6,7 +6,7 @@
import com.arextest.config.model.vo.QueryConfigOfCategoryResponse;
import com.arextest.model.mock.Mocker;
import com.arextest.storage.cache.CacheKeyUtils;
-import com.arextest.storage.client.HttpWepServiceApiClient;
+import com.arextest.storage.client.HttpWebServiceApiClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -28,7 +28,7 @@ public class QueryConfigService {
@Value("${arex.query.config.cache.expired.seconds:600}")
private long cacheExpiredSeconds;
@Resource
- private HttpWepServiceApiClient httpWepServiceApiClient;
+ private HttpWebServiceApiClient httpWebServiceApiClient;
@Resource
private CacheProvider redisCacheProvider;
@@ -52,7 +52,7 @@ public QueryConfigOfCategory queryConfigOfCategory(Mocker mocker) {
queryConfigOfCategoryRequest.setEntryPoint(mocker.getCategoryType().isEntryPoint());
queryConfigOfCategoryRequest.setOperationName(operationName);
QueryConfigOfCategoryResponse queryConfigOfCategoryResponse =
- httpWepServiceApiClient.jsonPost(queryConfigOfCategoryUrl, queryConfigOfCategoryRequest, QueryConfigOfCategoryResponse.class);
+ httpWebServiceApiClient.jsonPost(queryConfigOfCategoryUrl, queryConfigOfCategoryRequest, QueryConfigOfCategoryResponse.class);
if (queryConfigOfCategoryResponse != null && queryConfigOfCategoryResponse.getBody() != null) {
putConfigCache(appId, categoryName, operationName, queryConfigOfCategoryResponse.getBody());
return queryConfigOfCategoryResponse.getBody();
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/AgentRecordingController.java b/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/AgentRecordingController.java
index 599e9652..82d867f5 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/AgentRecordingController.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/AgentRecordingController.java
@@ -145,10 +145,11 @@ public Response saveTest(
@ResponseBody
public Response invalidCase(@RequestBody InvalidCaseRequest requestType) {
if (StringUtils.isEmpty(requestType.getRecordId())) {
- LOGGER.warn("agent invalid case recordId empty, {}", requestType);
+ LOGGER.warn("[[title=invalidCase]]agent invalid case recordId empty, {}", requestType);
return ResponseUtils.emptyRecordIdResponse();
}
- LOGGER.info("agent invalid case, request:{}", requestType);
+ MDCTracer.addRecordId(requestType.getRecordId());
+ LOGGER.info("[[title=invalidCase]]agent invalid case, request:{}", requestType);
CompletableFuture.runAsync(() -> agentWorkingMetricService.invalidCase(requestType));
return ResponseUtils.successResponse(true);
}
diff --git a/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/ScheduleReplayQueryController.java b/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/ScheduleReplayQueryController.java
index 72ec1c6e..2a024f18 100644
--- a/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/ScheduleReplayQueryController.java
+++ b/arex-storage-web-api/src/main/java/com/arextest/storage/web/controller/ScheduleReplayQueryController.java
@@ -17,6 +17,7 @@
import com.arextest.model.response.Response;
import com.arextest.storage.mock.MockerPostProcessor;
import com.arextest.storage.repository.ProviderNames;
+import com.arextest.storage.service.InvalidReplayCaseService;
import com.arextest.storage.service.PrepareMockResultService;
import com.arextest.storage.service.ScheduleReplayingService;
import com.arextest.storage.trace.MDCTracer;
@@ -53,6 +54,8 @@ public class ScheduleReplayQueryController {
private final PrepareMockResultService prepareMockResultService;
+ private final InvalidReplayCaseService invalidReplayCaseService;
+
/**
* fetch the replay result for compare
*
@@ -81,6 +84,7 @@ public Response replayResult(@RequestBody QueryReplayResultRequestType requestTy
scheduleReplayingService.queryReplayResult(recordId, replayResultId);
QueryReplayResultResponseType responseType = new QueryReplayResultResponseType();
responseType.setResultHolderList(resultHolderList);
+ responseType.setInvalidResult(invalidReplayCaseService.isInvalidCase(replayResultId));
return ResponseUtils.successResponse(responseType);
} catch (Throwable throwable) {
LOGGER.error("replayResult error:{} ,recordId:{} ,replayResultId:{}",
diff --git a/pom.xml b/pom.xml
index ce0e6d22..a89f88c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -408,5 +408,5 @@
https://github.com/arextest/arex-storage
- 1.0.48
+ 1.0.49
\ No newline at end of file