完成单机TEST统一入口与可靠投递回归收尾

This commit is contained in:
2026-09-29 19:48:34 +08:00
parent 64a70c9f28
commit 6c0a026cc4
89 changed files with 968 additions and 983 deletions
@@ -42,7 +42,8 @@ public class EventDeliveryFailure extends IllegalStateException {
&& ("NoFallbackAvailableException".equals(current.getClass().getSimpleName())
|| "No fallback available.".equals(current.getMessage()))) current = current.getCause();
String message;
if (current instanceof FeignException http) message = "HTTP " + http.status();
if (current instanceof feign.codec.DecodeException) message = "Invalid consumer response contract";
else if (current instanceof FeignException http) message = "HTTP " + http.status();
else if (current instanceof JsonProcessingException) message = "Invalid event JSON";
else message = current.getMessage() == null ? "unknown" : current.getMessage();
String text = current.getClass().getSimpleName() + ": " + message;
@@ -19,6 +19,7 @@ public final class EventDeliveryObservation {
public static String errorCode(Throwable error, boolean permanent, boolean requestStarted) {
Set<Throwable> seen = Collections.newSetFromMap(new IdentityHashMap<>());
for (Throwable cause = error; cause != null && seen.add(cause); cause = cause.getCause()) {
if (cause instanceof feign.codec.DecodeException) return "INVALID_RESPONSE";
if (cause instanceof FeignException http && http.status() >= 100 && http.status() <= 599) {
return "HTTP_" + http.status();
}
@@ -5,6 +5,7 @@ import com.baiyue.common.core.outbox.EventDeliveryProducer;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.context.annotation.Bean;
@@ -13,6 +14,7 @@ import org.springframework.transaction.PlatformTransactionManager;
@AutoConfiguration(after = {JdbcTemplateAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
@ConditionalOnBean(EventDeliveryProducer.class)
@ConditionalOnClass(name = "org.springframework.jdbc.core.JdbcTemplate")
public class EventDeliveryObservationAutoConfiguration {
@Bean
EventDeliveryJournal eventDeliveryJournal(JdbcTemplate jdbc, PlatformTransactionManager manager) {
@@ -5,6 +5,15 @@ import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
class EventDeliveryObservationTest {
@Test void malformedSuccessResponseIsNotReportedAsAnHttpSuccess() {
var request = feign.Request.create(feign.Request.HttpMethod.POST, "http://consumer.invalid/events",
java.util.Map.of(), new byte[0], java.nio.charset.StandardCharsets.UTF_8, new feign.RequestTemplate());
var failure = new feign.codec.DecodeException(200, "secret remote payload", request);
assertThat(EventDeliveryObservation.errorCode(failure, false, true)).isEqualTo("INVALID_RESPONSE");
assertThat(EventDeliveryFailure.diagnostic(failure, "token"))
.contains("Invalid consumer response contract").doesNotContain("secret", "HTTP 200");
assertThat(EventDeliveryFailure.isPermanent(failure)).isFalse();
}
@Test void auditIdentitySupportsTheFormalUuidAndUlidContractWithoutSavingMalformedPayload() {
var mapper = new ObjectMapper();
for (String id : new String[]{"00000000-0000-4000-8000-000000000019", "01ARZ3NDEKTSV4RRFFQ69G5FAV"}) {