Ok folks - I don't know if anyone is listening, but lemme give you an update
where I am on this.
Almost everything I am about to describe works, but is not yet checked in -
I'm adding more tests, and working on making all the adapters compatible.
First let's talk filters.
Here is how the you will add one to your app.
First off, you'll add them in the 'config/messaging.rb'.
I kept this b/c I wanted to keep them loosely coupled from the processors,
and be able to centrally control the order of them.
I sorta like the idea of adding them to a processor, as one would do with
before and after filters on a controller, but it just isn't the same.
ActiveMessaging::Gateway.define do |d|
d.destination :notify, '/queue/notify'
d.filter :authentication_filter, :direction=>:incoming,
d.filter 'my_app/current_user_filter', :direction=>:outgoing
d.filter LoggingFilter, :direction=>:bidirectional
So the filter method takes as a first argument a symbol, string, or class
The second argument is a hash of options that are used both for controlling.
The order filter declarations determines the order of their application.
The logic works like this: if it's a string or sym, figure out the class
from it (if a class is passed in, well that's the filter class).
If the class itself implements 'process(message,routing)', then the class is
used as the filter object.
If not, then a13g will instantiate the the class.
If the initialize method takes a single argument, then the hash of options
from the filter method call are passed in to the 'new' call.
If the initialize method takes no arguments, then that is called, and the
instance is used as the filter.
Filters have some standard options:
:direction [:incoming, :outgoing, :bidirectional (default)] - set which
direction of message send or get the filter is applied to.
Only makes sense for incoming or bidirectional message:
:except - set a single or array of destinations by symbol to exclude from
applying the filter.
:only - set a single or array of destinations by symbol to include when
applying the filter.
When you go to write a filter, you can add them anywhere they'll get loaded,
but I recommend adding them to app/processors/.
You can also start with extending the new 'abstract' Filter class I added to
a13g - and one thing I do need to add is a generator - I'll get to it.
The method to implements for filters is 'process(message, routing')
The 'message' argument is the actual message object, not just the body of
the message as processors get passed in.
The 'routing' info varies a but for incoming and outgoing - here are the
options that can be in this hash:
# :receiver=>processor class
# :destination=>destination object
# :direction => :incoming
# :publisher => publisher - optional
# :destination => destination object
# :direction => :outgoing
So that should give you something to work on.
Wanna implement a message translator, and change a message from a yaml or
json to xml or whatever? (
Great, you have access to the message object, and the body is mutable, so
change whatever you like before it gets to the processor, or in the other
direction, gets sent out to some other system.
Wanna implement an invalid message channel? (
Create a filter that validates a message, and if it is invalid, publish it
to a different queue and cease further processing.
But how do you cease further processing? Throw an
When thrown from a filter, this will cause all further work on a message to
end - meaning all downstream filters and processor get skipped.
Hopefully this gives a hint to some of the coolness that filters provide.
Looking at the EIP, there are not many that can't be done now with the
addition of filters.
Anything I am missing, or look bad in this?