fix: replay preload confirmation idempotently
This commit is contained in:
@@ -24,6 +24,7 @@ import com.baiyue.firstleg.loading.bridge.dto.LoadingModelBridgeDtos.Link;
|
||||
import com.baiyue.firstleg.repository.LoadingListRepository;
|
||||
import com.baiyue.firstleg.repository.LoadingPickRepository;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
@@ -553,17 +554,29 @@ public class LoadingListService {
|
||||
return "PL-" + sha256(operation + '|' + planId + '|' + normalized);
|
||||
}
|
||||
|
||||
private static void requireSameRequest(HistoryRow replay, String requestHash) {
|
||||
String snapshot = replay.getAfterSnapshot();
|
||||
if (snapshot == null || !snapshot.contains("\"requestHash\":\"" + requestHash + "\"")) {
|
||||
private JsonNode requireSameRequest(HistoryRow replay, String requestHash) {
|
||||
String rawSnapshot = replay.getAfterSnapshot();
|
||||
if (!StringUtils.hasText(rawSnapshot)) {
|
||||
throw conflict("Idempotency-Key 已用于不同请求");
|
||||
}
|
||||
try {
|
||||
JsonNode snapshot = objectMapper.readTree(rawSnapshot);
|
||||
JsonNode storedHash = snapshot == null ? null : snapshot.get("requestHash");
|
||||
if (storedHash == null || !storedHash.isTextual()
|
||||
|| !MessageDigest.isEqual(storedHash.textValue().getBytes(StandardCharsets.UTF_8),
|
||||
requestHash.getBytes(StandardCharsets.UTF_8))) {
|
||||
throw conflict("Idempotency-Key 已用于不同请求");
|
||||
}
|
||||
return snapshot;
|
||||
} catch (JsonProcessingException exception) {
|
||||
throw new IllegalStateException("无法读取装柜幂等快照", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private PreloadConfirmationResponse confirmationReplay(HistoryRow replay, String requestHash) {
|
||||
requireSameRequest(replay, requestHash);
|
||||
JsonNode snapshot = requireSameRequest(replay, requestHash);
|
||||
try {
|
||||
var response = objectMapper.readTree(replay.getAfterSnapshot()).get("response");
|
||||
JsonNode response = snapshot.get("response");
|
||||
if (response == null) throw new IllegalStateException("预装确认幂等响应缺失");
|
||||
return objectMapper.treeToValue(response, PreloadConfirmationResponse.class);
|
||||
} catch (JsonProcessingException exception) {
|
||||
|
||||
Reference in New Issue
Block a user