As I explained in the other thread, I've been working on a new API
for ServiceMix 4.0.
Hopefully this will serve as an input for JBI 2.0.
This API is available at https://svn.apache.org/repos/asf/incubator/
servicemix/branches/servicemix-4.0/api
So here a few key changes:
* clean integration with OSGi
* the NormalizedMessage can contain not only XML
* no more components
* no more JBI packaging (just use OSGi bundles)
* move the Channel to the Endpoint
* use push delivery instead of pulling exchanges
* introduce a single interface for identifying the Target of an
Exchange
As we remove components, everything goes down to the endpoint which
become a key feature.
The endpoint must implement the Endpoint interface. In OSGi, the NMR
would listen to endpoints
registered in the OSGi registry and call the registry to register /
unregister the endpoints.
As part of the endpoint registration, the NMR would inject a Channel
into them, thus actually activating the
endpoint. I guess I could write a sequence diagram for that (anybody
knows a good tool for uml ?).
In a non OSGI environment, the Endpoint will be registered in the
Registry by calling the register method
somehow.
The Endpoint receives Exchange to be processed on the process method.
I think we should keep the JBI 1.0 semantics and the endpoint use the
same process as for JBI 1.0, which is
send the exchange back using the Channel (with the response / fault /
error / done). This will put the threading,
transactions and security burden on the container itself. Which
means it is easier to write JBI apps :-)
Exchanges can be created using the Channel#createExchange method.
The only change I'd like to
integrate in the messaging API is to allow for non xml payloads and
maybe untyped attachments. The body
could be converted automatically to a given type if supported (I
think Camel does it nicely, so I'm thinking of
shamelessly copying the converter layer). I have added a few helper
methods on the exchanges and
messages (copy, copyFrom, ensureReReadable, display) to ease message
management.
For the deployment part, there is no packaging anymore. One would
deploy an OSGi bundle that would
register the needed endpoints in the OSGi registry. For certain
types of endpoints, we may need an external
activation process (such as creating a server socket for listening to
HTTP requests) that may need to be shared
across endpoints of a given type. In such a case, you would deploy a
"component" that listens to new
endpoints implementing HttpEndpoint for example. When a new endpoint
is registered, the listener would
activate a server socket that could be shared across all http
endpoints. In a different way, if we have a BPEL
engine, the bpel "component" would listen for new bundles and look
for a specific file containing deployment
information. The component would register new endpoints in the OSGi
registry as needed (we could do that
for jaxws pojos using cxf for example).
So I said there is no more components, because this feature is not in
the api anymore, but we will certainly need
these components for some use cases. For simple endpoints, you
would not need any component at all.
Another benefit is that you can easily deploy a whole application
inside a single OSGi bundle. Using spring-osgi,
the bundle would just consist in a spring configuration file
containing the endpoints declaration and expose them
as OSGi services.
Of course, we need to write a JBI 1.0 compatibility layer, and we
could have an intermediate layer where SAs and
JBI components could be OSGi bundles directly, thus leveraging the
OSGi classloading mechanism.
The thing I'm not completely sure about if the Target interface which
aims to identify the target of an exchange.
I'm thinking that some metadata are associated with endpoints (like
service name, interface name, wsdl
location, etc..). These metadatas could be used to retrieve targets
using the Registry. We could plug in different
mechanisms to query the metadata (simple lookup per id, policy based,
etc...). And the result itself could be
not only a single Endpoint, but could include some policies like:
load balance between all the endpoint implementing
the given interface, etc.... Also, I think Target should be injected
on Endpoints using spring, so you would look up a
targe using a spring bean factory (or multiple ones):
<smx:endpoint-target id="my-endoint-id" />
or
<smx:interface-target name="my:qname" />
The API is quite open right now, so any ideas welcome.
I think i covered the main areas of the API. The main goal is OSGi
and leveraging it as much as possible. There are
still some gray areas: what about the start/stop/shutdown lifecycle
which may be needed in some cases as I
discovered recently (when you want to gracefully shutdown a jms
consumer without loosing the ongoing messages
for example). I also want to give due credits to James, which has
been working with me on that.
Remember that nothing can't be changed and that' s why I'm asking for
feedback at this early stage, where there are
only ideas ;-)
Feedback welcome....
Cheers,
Guillaume Nodet