Class DualSchemaRegistryClient
- All Implemented Interfaces:
SchemaRegistryClient
Important — design clarification (R2 MAJOR fix): the "primary" and "fallback" delegates wrap the SAME underlying Apicurio registry. The dual client is NOT an HA hedge against registry outages; it's a wire-format coexistence layer. Both producers + consumers in a deployment may choose Apicurio 8-byte OR Confluent 4-byte wire prefixes, and the dual client makes both interpretations available against one Apicurio backend.
Behaviour:
register(String, byte[], SchemaType)— calls primary only. Any error from the primary (5xx / IOException / 4xx) propagates to the caller; the fallback is NEVER invoked at this method because it wraps the same underlying registry and retrying cannot recover from an outage there.fetchByGlobalId(long)— primary only. Apicurio globalIds (long) and Confluent schemaIds (int) are NOT interchangeable; a caller that has only a wire-prefix-derived id must pre-decide which method to invoke based on the wire format. Falling back here would silently mis-map ids.fetchLatestBySubject(String)— primary only; outages propagate (same rationale as register).kind()—SchemaRegistryClient.Kind.DUAL.wireFormat()— returns the primary's wireFormat (Apicurio 8-byte by default).
The fallback delegate is retained on this class so the wire-
format-hedging consumers may explicitly access it via getFallback();
routine register/fetch operations only ever consult the primary.
Activated when im2be.schema-registry.mode=dual.
-
Nested Class Summary
Nested classes/interfaces inherited from interface com.aim2be.platform.schema.SchemaRegistryClient
SchemaRegistryClient.Kind, SchemaRegistryClient.Schema, SchemaRegistryClient.SchemaType -
Constructor Summary
ConstructorsConstructorDescriptionDualSchemaRegistryClient(SchemaRegistryClient primary, SchemaRegistryClient fallback, io.opentelemetry.api.OpenTelemetry openTelemetry) -
Method Summary
Modifier and TypeMethodDescriptionfetchByGlobalId(long globalId) Fetches a schema by registry global ID.fetchLatestBySubject(String subject) Fetches the latest schema body registered undersubject.kind()Returns the implementation kind.longregister(String subject, byte[] schemaBytes, SchemaRegistryClient.SchemaType type) RegistersschemaBytesundersubject, returning the registry-assigned global ID.Returns the wire format this client emits / parses.
-
Constructor Details
-
DualSchemaRegistryClient
public DualSchemaRegistryClient(SchemaRegistryClient primary, SchemaRegistryClient fallback, io.opentelemetry.api.OpenTelemetry openTelemetry) - Parameters:
primary- the primary path (typically Apicurio 8-byte); not nullfallback- the fallback path (typically Confluent 4-byte); not nullopenTelemetry- the OpenTelemetry instance for tracer acquisition; not null
-
-
Method Details
-
register
Description copied from interface:SchemaRegistryClientRegistersschemaBytesundersubject, returning the registry-assigned global ID.Idempotent: a re-registration of identical bytes returns the same global ID (Apicurio's
IfExists=RETURN_OR_UPDATEsemantics).- Specified by:
registerin interfaceSchemaRegistryClient- Parameters:
subject- the subject name (typically<topic>-valueor<topic>-keyper ADR-0011 §B)schemaBytes- the schema body bytes; UTF-8 JSON for Avro/JSON, binary for Protobuf; must be non-nulltype- the schema type (AVRO / PROTOBUF / JSON)- Returns:
- the registry-assigned global ID
-
fetchByGlobalId
Description copied from interface:SchemaRegistryClientFetches a schema by registry global ID.- Specified by:
fetchByGlobalIdin interfaceSchemaRegistryClient- Parameters:
globalId- the global ID returned by a priorSchemaRegistryClient.register(java.lang.String, byte[], com.aim2be.platform.schema.SchemaRegistryClient.SchemaType)call- Returns:
- the schema record, or
nullif no such globalId. Sentinel-field contract: the Apicurio v2 REST API has no directglobalId → (subject, version)lookup, so impls that hydrate via the content-by-globalId endpoint return aSchemaRegistryClient.Schemawithsubject=""andversion=0as sentinels. Callers that need subject/version coordinates must useSchemaRegistryClient.fetchLatestBySubject(String)instead.
-
fetchLatestBySubject
Description copied from interface:SchemaRegistryClientFetches the latest schema body registered undersubject.- Specified by:
fetchLatestBySubjectin interfaceSchemaRegistryClient- Parameters:
subject- the subject name- Returns:
- the schema record, or
nullif no such subject
-
kind
Description copied from interface:SchemaRegistryClientReturns the implementation kind. Used for observability tagging (the kind shows up asschema.registryon every OTel span this client emits) and for callers that need to choose between Apicurio globalId semantics and Confluent schemaId semantics in their producer code path.- Specified by:
kindin interfaceSchemaRegistryClient- Returns:
- the implementation kind; never null
-
wireFormat
Description copied from interface:SchemaRegistryClientReturns the wire format this client emits / parses. Defaults toWireFormat.APICURIO_8_BYTE— the Apicurio native prefix.ConfluentWireCompatSchemaRegistryClientoverrides this toWireFormat.CONFLUENT_4_BYTE.- Specified by:
wireFormatin interfaceSchemaRegistryClient- Returns:
- the wire format; never null
-
getPrimary
- Returns:
- the primary delegate. Useful for diagnostic introspection.
-
getFallback
- Returns:
- the fallback delegate. Useful for diagnostic introspection.
-