Announcement Announcement Module
No announcement yet.
spring-integration based framework for running Java based services Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • spring-integration based framework for running Java based services

    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.

    New Requirements:
    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:
    for example:
    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.

    Question :
    * 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,

  • #2
    If many of your apps have the same basic flow, there are a few things you can do to modularize the flow to make it easier for each implementation to use.

    The simplest is to define the common flow with placeholders ${...} for the configurable properties, in one or more common files you provide to the apps in a jar; then, each application <import/>s the common flow(s) and provides a <util : properties/> object to provide values for the placeholders.

    The second approach would be to take a look at the spring-integration-flow project that David Turanski has started here

    With that technique, you put the flow behind a <flow:outbound-gateway/> and, again, provide the property values for the placeholders via <util : properties/> and pass it to the flow instance using a <flow/> element.

    A third approach would be a custom namespace that you are already exploring, but the first two would probably require less effort.