Class CompositeCodec

java.lang.Object
org.acemq.amqp.core.CompositeCodec
All Implemented Interfaces:
Codec

public final class CompositeCodec extends Object implements Codec
Writes in one format and reads several.

This is what makes changing format survivable. A queue during a cutover holds messages written by the old producers and the new ones at the same time, and a consumer that understands only one of them either loses the others or has to be deployed in lockstep with every producer. Reading both for a while, and writing only the new one, turns a flag day into two ordinary releases: deploy the consumers that read both, then the producers that write the new format, then drop the old codec once the queue has drained.

Encoding always uses the first codec, and there is no way to configure otherwise. Choosing an encoding per message would need a rule for choosing, and every such rule turns into a question the caller has to answer at each publish; one format out, several in, is the shape that migrations actually need.

A message whose content type matches nothing is offered to every codec in turn, because a sender that set no content type has told us nothing rather than told us it is unreadable, and something on the wire is usually still readable by one of them.

  • Method Details

    • of

      public static CompositeCodec of(Codec... codecs)
      Parameters:
      codecs - codecs to read with; the first is also the one written with
      Returns:
      a codec that writes the first format and reads any of them
    • contentType

      public String contentType()
      Specified by:
      contentType in interface Codec
      Returns:
      the content type this codec produces, for example application/json
    • encode

      public byte[] encode(Object payload)
      Specified by:
      encode in interface Codec
      Parameters:
      payload - object to encode; never null
      Returns:
      encoded bytes
    • decode

      public <T> T decode(byte[] body, Class<T> target)
      Specified by:
      decode in interface Codec
      Type Parameters:
      T - target type
      Parameters:
      body - encoded bytes
      target - type to produce
      Returns:
      the decoded payload
    • decode

      public <T> T decode(byte[] body, Class<T> target, @Nullable String contentType)
      Description copied from interface: Codec
      Decodes a received message, told what the sender said it was.

      The engine calls this one, because a codec that dispatches between several formats cannot choose without knowing the content type. A codec that handles a single format has no use for it and need not override this.

      Specified by:
      decode in interface Codec
      Type Parameters:
      T - target type
      Parameters:
      body - encoded bytes
      target - type to produce
      contentType - content type the message arrived with, or null when the sender did not set one
      Returns:
      the decoded payload
    • canDecode

      public boolean canDecode(@Nullable String contentType)
      Specified by:
      canDecode in interface Codec
      Parameters:
      contentType - content type of a received message, or null when the sender did not set one
      Returns:
      whether this codec can decode it
    • codecs

      public List<Codec> codecs()
      Returns:
      the codecs this one reads with, in the order they are tried
    • toString

      public String toString()
      Overrides:
      toString in class Object