On Aug 23, 2007, at 11:58 AM, James Strachan wrote:
On 8/22/07, Nodet Guillaume <[EMAIL PROTECTED]> wrote:
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
Sounds great!
How far have you got implementing this? :)
Not so far yet. I've played a bit with OSGi last month in a branch,
but not much on this very api...
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'd hope we can easily just wire in camel-core as the default type
converter layer implementation as we've got most common type
conversions sorted now along with a simple extension mechanism to
support any type conversions. i.e. you should be able to invoke the
type conversion stuff without the SMX API having any hard dependency
on Camel - let it be just an implementation detail.
Yeah, we certainly need to work on the details. I will continue
discussing
that by replying to your other email.
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.
Interesting differentiation between component and endpoint; I like it.
My main point is that usually an endpoint is sufficient by itself. At
least the NMR
only needs to know about endpoints. Components are needed when
additional
resources or deployment mechanism need to be handled.
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).
I wonder should we come up with some standard OSGi metadata that
components should try adopt to know when to auto-detect things like
HttpEndpoint or BPEL. I guess component developers can do whatever
they like but it might be nice to at least document some guidelines
for nicely behaving components
I think if you deploy java code, you can easily use an interface to
recognize
endpoints of a certain type. This is the easiest way imho. For a
BPEL process
you can always register a BpelEndpoint that contains a pointer to the
needed
resources (bpel process and wsdls). This may not be nicest way to
handle things,
but this allow to more tightly control which endpoints are created.
If we search the
bundle for known resources (a wsdl or bpel for example), we may have
conflicts
where differents components would try to activate an endpoint for the
same resource.
Another way would be to use some metadata in the META-INF folder of
the bundle
to list the endpoints to be activated. Imo, the first solution is
the most straightforward.
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.
Yeah - I think usually most folks are gonna wanna work with a smart
proxy to the available endpoints rather than the actual physical
endpoints themselves (since in OSGi they can come and go at will).
If we can express most of the query semantics in standard OSGi LDAP
syntax, the above XML elements could just be helper classes sitting on
top of the standard Spring-OSGi smart proxies. We'd just need our own
smart proxy providers for more complex types of predicates; such as
using all the endpoints which implement some kinda WS-Policy assertion
or whatever which maybe cannot be expressed as a standard OSGi query.
I think i covered the main areas of the API.
One topic not covered in this excellent post is a standard mechanism
to provide access to other endpoint metadata (e.g. the WSDL file) -
having that as a standard OSGi metadata would be cool (e.g. a WSDL
URI)
Yeah, I have had a closer look at how OSGi provides URL handlers.
This is not as simple as I thought it would be. OSGI defines
a "bundle:" protocol that can be used to access resources in the bundle.
Unfortunately, the url has to contain the bundle id, which means that
the URLs have to be built dynamically. I'm sure we can create a spring
bean factory to create those dynamically though...
Or a post factory processor that would process the URIs to rewrite them
and include the bundle id.
This way, the service could contain a WSDL_URL property associated
with it (when registered in the OSGi registry) that would be a bundle
url
pointing to the wsdl inside the bundle. This would solve one of JBI
limitation
which is the ability to have complex WSDLs definitions including other
WSDL or XSD.
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.
Thanks! :)
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 ;-)
Its an awesome start! Once the basics are working we can try port some
components across; then we might find more issues etc.
--
James
-------
http://macstrac.blogspot.com/
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/