we are building a service-container framework using spring-integration 2.1-GA (SI) as our platform.
the idea is to replace legacy services that currently use tuxedo.
a service in our context is a an AMQP listener.Thus, hosting services implies hosting AMQP listeners.
we use SI's AMQP gateway to connect to RabbitMQ , where each service entity, represented by a java interface with multiple methods, listens to a single
RabbitMQ queue. Unmarshalling and routing to the "correct" method within the interface is achieved using an unmarshaller, router/header-enrichers..
* It's also required that we support the full suite of SI.
What was done:
* A POC based on the above design, was functionaly satisfactory - both performance and usage-wise.
Motivation for new requirements:
However, there was a huge criticism regarding # of lines and the copious verbosity required to achieve this.
for example to advertize one AMQP listener, we had the following:
1. define an amqp-inbound gateway with request and response channels and # of concurrent consumers.
2. define request/response channels for the gateway
3. wire the request channel to a framework defined marshaller/unmarshaller(M/U)
4. define an input channel to get data from the framework M/U
5. wire this input channel to a router that delegates the message to the appropriate service-activator channels.
6. define input/output channel pair for each service-activator required to process the message.
7. define a service-activator for each method defined in the interface.
8. wire output-channel of service-activator to the framework M/U ( which in turn binds this channel to amqp-gateway "automagically")
9. define the exchange,binding keys to the single queue.
here, we are only describing the configuration from the user's perspective.
1. convention over configuration - come up with reasonable defaults w.r.t defining gateways,channels,exchanges,queues, binding keys.
2. restrict the spring-context to defining the method and the associated bean, thus reducing verbosity.
Our approach thoughts:
* use own namespace to control default attributes and wire the rest automagically:
spring context may look like
<framework:service-activator method="M1" bean="B1"/>
<framework:service-activator method="M2" bean="B1"/>
<framework:service-activator method="M3" bean="B1"/>
behind-the-scenes, the "framework" NS is handled by configuring the steps 1. through 9. in the "Motivation of requirements" section.
exchange names will be equal to "B1".
routing key names will be equal to "M1,M2,M3".
queue name will be equal to "B1".
any configuration that uses the "framework" NS will be configured as an amqp listener.
the idea is to use the "thinnest possible" layer to extend spring-integration, hopefully via api-hooks and not via inheritance.
this is to keep up with latest changes and take advantage of new components as and when they are released.
Our approach precludes mix-and-or-match.context files that define "framework" NS's will not work with pure SI based contexts.
Our approach does move away from explicit configuration of SI components, which seems to be the basic philosophy of using SI.
but the idea is to get a simple service declaration without so much configuration.
* Do you think we are getting the right direction?
** If not - what could be done to achieve our Goal?
* What can be used in SI as it is today to achieve our Goal?
* If the direction is right - what's the best way to achieve it?
Thanks for your advice/comments in advance,