Ok, how about this?

For direct messaging between producers and consumers:

Direct multicast delivery (one copy to every subscriber to the address):

    route {
        address: service.mcast
        type: direct
        treatment: multicast
    }


Direct delivery to only the closest (lowest cost) subscriber:

    route {
        address: service.regional
        type: direct
        treatment: closest
    }


Direct delivery to one subscriber favoring subscribers that settle deliveries more quickly.

    route {
        address: service
        type: direct
        treatment: balanced
    }


For messaging involving a queue, topic, or other intermediate process. In these cases, the remote container may be identified by container-id or connection label (container-id shown in examples):

Link-routing to a queue:

    route {
        address: my_queue
        type: waypoint
        treatment: linkBalanced
        container: <broker-container-id>
    }


Link-routing only for enqueue:

    route {
        address: my_queue
        type: sink
        treatment: linkBalanced
        container: <broker-container-id>
    }


Link-routing only for dequeue:

    route {
        address: my_queue
        type: source
        treatment: linkBalanced
        container: <broker-container-id>
    }


Simple queue waypoint (treatment defaults to 'balanced'):

    route {
        address: my_queue
        type: waypoint
        container: <broker-container-id>
    }


Simple topic waypoint that supports selectors:

    route {
        address: my_topic
        type: waypoint
        inTreatment: multicast
        outTreatment: linkBalanced
        container: <broker-container-id>
    }


Distributed (sharded) queue waypoint:

    route {
        address: my_queue
        type: waypoint
        container: <broker-1-container-id>
    }
    route {
        address: my_queue
        type: waypoint
        container: <broker-2-container-id>
    }


Distributed (sharded) topic waypoint:

    route {
        address: my_topic
        type: waypoint
        inTreatment: multicast
        outTreatment: linkBalanced
        container: <broker-1-container-id>
    }
    route {
        address: my_topic
        type: waypoint
        inTreatment: multicast
        outTreatment: linkBalanced
        container: <broker-2-container-id>
    }


=====================================================================
Syntax:

route: {
    type: direct | source | sink | waypoint
    address: (address or prefix)
    treatment: multicast | closest | balanced | linkBalanced
    connector: (label of a connection to/from a remote container)
    container: (ID of a connected remote container)
    inTreatment: (override treatment for inbound traffic)
    outTreatment: (override treatment for outbound traffic)
    inAddress: (override address for inbound traffic)
    outAddress: (override address for outbound traffic)
}


Some notes:

- I don't care for the negative connotations of "detour" and prefer
  "waypoint" for describing a thing you must go through on your way to
  the final destination.
- I've replaced "fanout" + "bias" with "treatment" to describe how the
  router handles the forwarding of messages.  There is precedent for
  the use of this term (hat tip to Andy Smith) in Cisco's router
  documentation.
- Link-routing is just another kind of treatment, like multicast or
  closest-consumer.  This removes the need for the "mixed" route as
  described by Gordon.  It also removes any distinction between a
  waypoint and a link-route-destination as a link-route-destination
  simply becomes a waypoint with linkBalanced treatment.
- I'm avoiding Alan's distinction between direct and indirect routes by
  noting that "direct" is the only direct option whereas the other
  types are indirect.
- The notion of "direction" is replaced by the "source" and "sink"
  route types.


-Ted



On 02/24/2016 09:18 AM, Alan Conway wrote:
Minor update attached - I included Gordon's point about indirect routes
being able to use a listener to accept an incoming broker connection as
well as a connector to make an outgoing one, the new part:

----
Indirect routes can use incoming connections from the external
application by specifying a `listener` instead of a `connector` and an
AMQP `container` name to identify the external application.

      indirectRoute {
          address: my_queue  # TODO address patterns.
          listener: secure_broker_listener
          container: "mybroker-container-id"
          mode="message"
      }
----

Here's the full thing:

===========
Terminology
===========

AMQP messages are sent on *links*. A link that sends messages from an
application to a dispatch router is a *sender*. A link that receives
messages for an application from a dispatch router is a *receiver*.

Dispatch router configuration defines *routes*. A route has an
*address*. Addresses can be AMQP address strings or patterns (TODO)

Incoming client links (senders or receivers) are attached to the route
with a matching address. If a sender link has no address, messages are
routed individually using the *to* address. Receiver links with no
address are not allowed.

There are several types of route:

A *directRoute* accepts sender and receiver links and forwards messages
from senders to receivers. This allows clients to communicate directly
without the need for a broker.

Example: direct route "foo" with fanout (replaces fixedAddress)

     "directRoute": { "address": "foo",  "fanout": "multiple" }

An *indirectRoute* creates links to an external application (such as a
broker) and forwards messages from senders to the application, and
messages from the application to receivers. There are two modes:

  - message routing: the route creates its own links to the external
application, there is no relationship with the sender/receiver links.
  - link routing: the route creates external links that correspond
exactly with sender/receiver links. It forwards all link information
(name, flow control, properties etc.) to the external application.

Link routing preserves more AMQP context between the client and the
external application. Message routing offers more flexibility to modify
the message flow e.g. to load balance messages over multiple brokers.

An indirectRoute can initiate a connection to the external application
or accept an incoming connection from it.

Example: broker integration with link routing (replaces
linkRoutePattern)

      indirectRoute {
          address: my_queue  # TODO address patterns.
          connector: my_broker
          mode="link"
      }

Example: broker integration with message routing (replaces simple
waypoint)

      indirectRoute {
          address: my_queue  # TODO address patterns.
          connector: my_broker
          mode="message"
      }

Indirect routes can use incoming connections from the external
application by specifying a `listener` instead of a `connector` and an
AMQP `container` name to identify the external application.

      indirectRoute {
          address: my_queue  # TODO address patterns.
          listener: secure_broker_listener
          container: "mybroker-container-id"
          mode="message"
      }

For more complex cases routes can create links to other routes. Routes
always allow internal links, but a route can be configured to allow
only senders, receivers, both or none from outside. An external link is
attached to the route that has the right its address *and* allows that
link type. A route with `"allow": "none"` is an internal routing detail
and cannot be accessed directly by clients.

Example: waypoint chaining

      # Route for messages sent to my_queue, forward to broker1
      indirectRoute {
          address: my_queue
          allow: sender
          connector: broker1
          mode: message
      }

      # Internal route for messages coming back from broker1, forward to
broker2
      indirectRoute {
          address: my_queue
          allow: none  # internal only
          connector: broker1
          internalSender: ["broker2"] # send to broker2
          mode: message
     }

      # Route messages through broker2 and then back to receivers.
      indirectRoute {
          internalAddress: "broker2"
          connector: broker2
          allow: receiver
          mode: message
      }

Example: message-routing with load balancing over two brokers.

      # Route for senders to my_queue.
      directRoute {
          address: my_queue
          allow: sender
          internalSenders: ["broker1_my_queue", "broker2_my_queue"]
          fanout: multiple
      }

      # Route for receivers from my_queue.
      directRoute {
          address: my_queue
          allow: receiver
          internalReceivers: ["broker1_my_queue", "broker2_my_queue"]
      }

      # Internal route to broker1
      indirectRoute {
          internalAddress: broker1_my_queue
          allow: none
          connector: broker1
      }

      # Internal route to broker2
      indirectRoute {
          internalAddress: broker2_my_queue
          allow: none
          connector: broker2
      }

TODO:

- indirect route with multiple listeners/connectors with/without
container name giving multiple choices of external apps. Policy
controol: link routes can't fan-out but they can load balance.
- mix link & message routes: "tap" messages from a link route and
message route them.
- pattern matching
- internal address rewriting?
- multi-tennant




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to