Class RoutingSlip

java.lang.Object
org.acemq.amqp.api.RoutingSlip

public final class RoutingSlip extends Object
Where a message is going, carried by the message.

A pipeline has no coordinator. Each step reads the slip, does its work, advances the position and publishes to whatever comes next; when the position runs off the end, the run is over. That is choreography rather than orchestration, and the difference is worth the two headers it costs:

  • There is no flow engine to run, page somebody about, or upgrade — nothing to be down.
  • A consumer in Go reads three headers. The Java library is not privileged.
  • The state survives a restart, because it is in the message rather than in a coordinator's memory.
  • A message dead-lettered at step two keeps its slip, so replaying it resumes the run instead of starting it again.

The cost, and it is a real one: the route is fixed when the message is first sent. Changing a pipeline does not change messages already travelling, which finish along the route they were given. During a deploy that is usually what anyone would want, and it is occasionally surprising.

Steps are named rather than numbered on the wire, so a slip stays readable in a management console: validate,enrich,dispatch with a position of 1 says exactly where a message is without anybody decoding anything.

  • Field Details

  • Method Details

    • startOf

      public static RoutingSlip startOf(List<String> steps)
      Parameters:
      steps - the step names, in order
      Returns:
      a slip at the beginning of that route, with a fresh run identifier
    • from

      public static Optional<RoutingSlip> from(Map<String,Object> headers)
      Reads a slip off a message's headers.
      Parameters:
      headers - the message headers
      Returns:
      the slip, or empty when the message is not travelling a route
    • current

      public Optional<String> current()
      Returns:
      the step this message is for now, or empty when the route is finished
    • next

      public Optional<String> next()
      Returns:
      the step after the current one, or empty when this is the last
    • advanceTo

      public RoutingSlip advanceTo(int position)
      Parameters:
      position - which step to start at
      Returns:
      a slip positioned there, for a message replayed straight into a queue with no slip of its own
    • advance

      public RoutingSlip advance()
      Returns:
      a slip advanced by one step
    • isFinished

      public boolean isFinished()
      Returns:
      whether every step has been handled
    • steps

      public List<String> steps()
      Returns:
      the steps, in order
    • position

      public int position()
      Returns:
      which step is next, counting from zero
    • runId

      public String runId()
      Returns:
      the identifier of this run, stable across every hop, a dead-letter and a replay
    • toHeaders

      public Map<String,Object> toHeaders()
      Returns:
      the headers to publish this slip with; merge them into an envelope's own
    • startOf

      public static RoutingSlip startOf(String... steps)
      Parameters:
      steps - step names
      Returns:
      a slip at the start of that route
    • toString

      public String toString()
      Overrides:
      toString in class Object