Class VersionedMessageAdapter

java.lang.Object
com.loomcache.common.protocol.VersionedMessageAdapter

public final class VersionedMessageAdapter extends Object
Adapts message encoding/decoding to be version-aware.

Responsibilities: 1. Wrap message codec to enforce version constraints 2. Implement forward compatibility: unknown message types from newer versions are safely ignored 3. Implement backward compatibility: provide graceful errors for unsupported operations on older versions 4. Track negotiated version per connection

Forward compatibility strategy: - If a newer peer sends a message type unknown to this version, log it and skip - This allows the cluster to continue operating during rolling upgrades

Backward compatibility strategy: - Reject operations requiring features not available in negotiated version - Return appropriate error responses to clients

Thread-safe: Each connection has its own adapter instance.

  • Constructor Details

    • VersionedMessageAdapter

      public VersionedMessageAdapter(VersionCompatibilityManager compatibilityManager, LoomVersion negotiatedVersion, @Nullable String peerId)
      Create a versioned message adapter.
      Parameters:
      compatibilityManager - the compatibility manager (must not be null)
      negotiatedVersion - the version negotiated with remote peer (must not be null)
      peerId - the remote peer's identifier (may be null)
      Throws:
      IllegalArgumentException - if compatibilityManager or negotiatedVersion is null
  • Method Details

    • negotiatedVersion

      public LoomVersion negotiatedVersion()
      Get the negotiated version for this connection.
      Returns:
      the negotiated version
    • peerId

      public @Nullable String peerId()
      Get the remote peer's identifier.
      Returns:
      the peer ID, or null if not set
    • encode

      public ByteBuffer encode(Message message)
      Encode a message, ensuring the message type is supported in the negotiated version.

      If the message type is not suitable for the negotiated version, logs a warning.

      Parameters:
      message - the message to encode (must not be null)
      Returns:
      the encoded message as a ByteBuffer
      Throws:
      IllegalArgumentException - if message is null
    • decode

      public @Nullable Message decode(ByteBuffer buffer)
      Decode a message from a ByteBuffer, implementing forward compatibility.

      If a newer peer sends a frame with an opcode unknown to this version and the codec has already advanced past that frame, returns null and logs it. Same-version or older peers still fail fast so the caller can close the connection.

      Parameters:
      buffer - the encoded message buffer (must not be null)
      Returns:
      the decoded message, or null if a newer peer sent an unknown opcode after the frame was skipped, or EOF
      Throws:
      IllegalArgumentException - if buffer is null
    • hasFeature

      public boolean hasFeature(Feature feature)
      Check if a feature is available for this connection.

      This is useful before processing operations that require specific features.

      Parameters:
      feature - the feature to check (must not be null)
      Returns:
      true if the feature is available in the negotiated version
      Throws:
      IllegalArgumentException - if feature is null
    • createFeatureUnavailableError

      public Message createFeatureUnavailableError(Feature feature, int correlationId)
      Create an error message for an unsupported operation.

      Used when a client tries to use a feature not available in the negotiated version.

      Parameters:
      feature - the unsupported feature (must not be null)
      correlationId - the correlation ID to echo back
      Returns:
      an error response message
      Throws:
      IllegalArgumentException - if feature is null