Implementations should operate on a transport envelope or header collection, never on a + * business DTO. Micrometer uses the inherited getter and setter to extract and inject propagation + * fields without exposing a concrete tracing implementation to the transport.
+ */ +public interface MessageCarrierAdapterThe message carrier owns transport metadata. Business payloads remain independent from + * Micrometer, OpenTelemetry, MDC, and a concrete tracing backend. A transport integrates by + * providing a {@link MessageCarrierAdapter}, then wrapping the actual send and per-message + * processing operations with this component.
+ */ +@Component +public class MessageObservationSupport { + + /** + * Reserved transport field for log correlation when distributed tracing is disabled. + */ + public static final String REQUEST_ID_FIELD = "skillhub.request_id"; + + // The propagation boundary owns these fields. Removing existing values prevents business + // metadata from forging a parent trace or leaking stale context into a newly published message. + private static final SetThe thread-local value is authoritative. MDC is maintained only as a mirror for log + * correlation.
+ */ +@Component +public class RequestIdAccessor { + + public static final String MDC_KEY = "requestId"; + + private static final Pattern VALID_REQUEST_ID = + Pattern.compile("^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$"); + + private final ThreadLocalRedis Stream entries do not have a separate header collection, so reserved propagation fields + * share the entry map with business fields. {@code MessageObservationSupport} owns and sanitizes + * those reserved fields; business payload types remain unaware of them.
+ */ +final class RedisStreamMessageCarrier { + + static final String MESSAGING_SYSTEM = "redis"; + + static final MessageCarrierAdapter