On Tue, Mar 26, 2013 at 7:19 AM, Bozo Dragojevic <bo...@digiverse.si> wrote:

> On 3/23/13 5:43 PM, Rafael Schloming wrote:
>
>> Hi,
>>
>> I've added a new API to messenger that gives the user some control over
>> the
>> internal routing behaviour of a messenger. Please check it out and
>> comment.
>> I've pasted the C API/doxygen below. This is currently only exposed
>> through
>> the python binding via the route method on the Messenger class.
>>
>> --Rafael
>>
>> /** Adds a routing rule to a Messenger's internal routing table.
>>   *
>>   * The route procedure may be used to influence how a messenger will
>>   * internally treat a given address or class of addresses. Every call
>>   * to the route procedure will result in messenger appending a routing
>>   * rule to its internal routing table.
>>   *
>>   * Whenever a message is presented to a messenger for delivery, it
>>   * will match the address of this message against the set of routing
>>   * rules in order. The first rule to match will be triggered, and
>>   * instead of routing based on the address presented in the message,
>>   * the messenger will route based on the address supplied in the rule.
>>   *
>>
>
> Can you help me work through this use-case:
>
>
> A 'dumb' client, sends a message, and expects a reply:
>
>     // client.c
>     pn_message_set_address(msg, "amqp://localhost/bla");
>     pn_messenger_put(msgr, msg);
>     pn_messenger_receive(msgr,1);
>     msg = pn_messenger_get(msgr);
>
>
>
> The peer it connects to uses the new route functionality:
>
>     // server.c
>     pn_messenger_subscribe(msgr, "~amqp://localhost/bla");
>

I'm assuming you mean "amqp://~localhost/blah" above. ;-)


>
> 1) Are routes valid to use if there's a subscribe going on.
>    I assume yes.
>
>     pn_messenger_route(msgr, "*", "amqp://broker/$1");
>

It's certainly valid to use both at the same time.


>
> 2) How do they interact.
>    I assume they don't, routing is only applied to outgoing messages.
>

Actually routing should be applied equally to both, however now that I
think about it I suspect you need to do the route before you do the
subscribe in order for it to make a difference for the subscribe, although
I expect that limitation to go away in the next round of changes.


>
> 3) Does the order of calls to route and subscribe matter.
>    According to 2) it does not.
>

Actually the order does matter (see above). I expect eventually the
implementation will evolve in such a way that the order does not matter,
however even so you would effectively end up getting a resubscribe when the
new route goes into place, e.g. the following sequence of events could
occur:

subscribe("foo.com/bar")
...
... if you do a recv here, messages might arrive directly from foo.com
...
route("foo.com/bar", "fooproxy.com/baz")
...
... now you get messages via the proxy


>
>     pn_messenger_receive(msgr, 1);
>     msg = pn_messenger_get(msgr);
>
>     /* echo */
>     char *sender = pn_message_get_reply_to(msg);
>     pn_message_set_address(msg, sender);
>     pn_messenger_put(msgr, msg);
>     pn_messenger_send(msgr);
>
>
> 4) What would the pn_message_get_reply_to() return.
>    The value as set by the client's messenger would be
> amqp://some-uuid-value
>

This is a very good question. I don't recall exactly why messenger sets the
reply_to automatically as it does, it may even be an unintentional side
effect of a couple of different changes, but I've been thinking that it
shouldn't actually do this automatically, i.e. that you should always set a
reply_to explicitly if that's what you want.

FWIW, it's not actually setting the reply_to value to some-random-uuid,
it's actually setting it to amqp://the-name-of-the-messenger. It just so
happens that the name of the messenger defaults to a UUID, but if you had
constructed your messenger as pn_messenger("bob") rather than
pn_messenger(NULL), then the reply_to would automatically get set to
amqp://bob.

I was also thinking that it would be convenient to have some way to
actually refer to the container name in an address, that way e.g.
explicitly setting the reply_to = "amqp://${me}" would give the same effect
that you currently get with the automatic setting, but would also be a bit
more flexible.


>
> 5) Would the route above apply or not to this particular outgoing reply
> message.
>

The rules always apply, the messenger impl doesn't really know the
difference between that and any other address.


>
> 6) If yes, how will 'broker' learn how to talk to the original client
>

Another very good question. Unfortunately the answer right now depends on
your broker as each broker assumes a private namespace, you would need to
construct a reply_to that is known to your broker, e.g. create a
reply-queue called "replies" on your broker and explicitly set your
reply-to to amqp://broker/replies.

One of the areas that we are working on within the OASIS TC is defining an
addressing standard such that this will be much more seamless, e.g. the
clients could just use globally scoped names the same way they would in a
peer to peer scenario, and you could have an intermediary that would be
able to identify these and route/proxy accordingly. Obviously a legacy
broker wouldn't necessarily function as a router/proxy, so you still might
need to manually stitch together the reply-to chain depending on what kind
of intermediary you are using.

One thing worth pointing out about this functionality that might not be
obvious at first is that the route function doesn't currently touch what is
in the to or reply-to field of a message. That always stays exactly as the
user supplies it. The model is really a world where logically the to and
reply-to identify a final destination/rendezvous point and therefore need
to be preserved and carried forward by every intermediary in the network.
Hence the name pn_messenger_route as what it is doing is determining the
next hop, not doing some sort of rewriting.

It would, however, be possible to add an API that used the same or a
similar mechanism to do rewriting, e.g. pn_messenger_rewrite(pn_messenger_t
*m, const char *pattern, const char *address) could establish a distinct
set of rules for rewrite the to/reply_to of incoming and/or outgoing
messages. I can imagine this possibly being useful in legacy scenarios
where you need the reply_to to match a particular form required for a given
broker.

--Rafael

Reply via email to