You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by James Strachan <ja...@gmail.com> on 2007/03/23 16:09:22 UTC

Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

On 3/23/07, Liu, Jervis <jl...@iona.com> wrote:
> Hi, I've been experimenting a bit on the service routing lately, the result has been put on the wiki: http://cwiki.apache.org/confluence/display/CXF20DOC/Service+Routing. So it works ((I will check in a system test shortly), my main concern though, is that this implementation does not seem to be very "simple", it does require a fair amount of knowledge of CXF internal. Not sure if it is appropriate to expose this to CXF userland. Anyway, I am open to any comments&suggestions.
>
> Thanks,
> Jervis
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: 2007?3?17? 3:32
> > To: cxf-dev@incubator.apache.org
> > Subject: Re: Release Update
> >
> >
> > On 3/15/07, Liu, Jervis <jl...@iona.com> wrote:
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > > > Sent: 2007?3?15? 21:44
> > > > To: cxf-dev@incubator.apache.org
> > > > Subject: Re: Release Update
> > > >
> > > >
> > > > Hi Jervis,
> > > >
> > > > I wanted to ensure that we can setup an endpoint on a URL
> > and route to
> > > > different services based on headers (such as ws-a) or other
> > > > logic.  I made a
> > > > series of proposals about how to do this a while back, but I
> > > > don't think we
> > > > ever came to any concrete conclusion.
> > > >
> > > Ok, I see what you mean. I believe you are referring to
> > this proposal [1].
> > > One thing I have not figured out from the proposal yet is
> > how we know the
> > > addresses of services to which the routing service is about
> > to redirect?
> > > Through some kind of registries or a configuration loaded
> > from a separate
> > > file or a WSDL extension.? Once this kind of discussion
> > gets started, I do
> > > not see how it can end by the end of this release. Service
> > routing is a huge
> > > topic anyway. However we will have much less to worry about
> > if we are not
> > > after a complete resolution of service routing. For
> > example, if we only
> > > support the routing among different endpoints within the
> > same Destination,
> > > would this feature be considered helpful for some certain
> > use cases? Reading
> > > your proposal, I believe this is also what you want to do,
> > start from sth
> > > simple first. If this is the case, I am ready to get my
> > hands dirty now.
> > >
> > > BTW, I am in a traveling at the moment, I may not respond
> > in time until I
> > > get back to office next Tuesday.
> > >
> > > [1].
> > >
> > http://mail-archives.apache.org/mod_mbox/incubator-cxf-dev/200
> 612.mbox/%3c7b774c950612021343x513c2783o128a032ba93923bb@mail.gmail.com%3e
>
>
>
> Yes, I'm really just concerned about the simple case. Namely being able to
> create some type of routing endpoint which routes to other types of
> services. My main use cases is versioning of services. Ideally many services
> can share the same URL and I can route by headers or the namespace of the
> body part.
>
> Regarding how to know what services to route to - I think its up to the user
> to write that code. I was kind of envisioning that it'd be an interceptor
> that a user writes. We could build something more formal like a registry,
> but we would need something low level first :-)

Sorry to hijack this thread; a bit of background first then I'll get
more on topic...

On the ActiveMQ and ServiceMix projects we've wanted a simple POJO
router for a while thats

* Apache Licensed
* small & simple with minimal dependencies (just commons-logging)
* allows routes to be defined easily in Java code or using Spring XML
* can work with any of the various messaging models and APIs from
HTTP, JMS, JBI, CXF, JAX-WS, MINA etc

A little experimental library soon turned into a fairly full featured
router very quickly. The documentation is still quite sparse, but let
me introduce you to Apache Camel...
http://activemq.apache.org/camel/

Here's a quick example to give you the idea...
http://activemq.apache.org/camel/routes.html

We've been documenting how the Enterprise Integration Patterns can be
implemented using Camel
http://activemq.apache.org/camel/enterprise-integration-patterns.html

Here's a quick overview of the architecture (we'll document this way
better soon)
http://activemq.apache.org/camel/architecture.html


One of the interesting things about Camel is it can work with any
underlying protocol using a small & simple API (similar to a
simplification & generalization of both CXF Bus API and JBI).  Not
only that, thanks to generics and covariant return types we can work
explicitly with specific protocols when required in a nice typesafe
manner to avoid leaky abstractions.

e.g.

// A JMS specfic processor
class Foo implements Processor<JmsExchange> {
  public void onMessage(JmsExchange exchange) {

    // lets do some direct JMS stuff..
    javax.jms.Message message = exchange.getInMessage();
  }
}

So we could easily route from JMS to CXF to JBI and into MINA say.

Enough of all that, lets show an example thats more releative to CXF...

RouteBuilder<Exchange> builder = new RouteBuilder<Exchange>() {
    public void configure() {

        // a declarative routing rule example
        from("cxf:myservice").choice()
                .when(version().isEqualTo("1.2")).to("cxf:myservice1.2")
                .when(xpath("/foo/bar[@cheese =
'edam')).to("cxf:myOtherService")
                .otherwise().to("jms:Error.Queue");
    }
};

In this particular case we're using a custom expression version()
which could be any old Expression<Exchange> implementation.


I think Camel could be useful for arbitrary declarative routing and
mediation rules in CXF. I've taken an early stab at supporting CXF Bus
API in Camel...

https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-cxf/

I've got the main parts done (the exchange & message pieces), I'm just
not sure yet in the CxfEndpoint how to bind inbound exchanges to the
CXF bus and back again nicely. Also it'd be nice to resolve URI
endpoints in Camel nicely to auto-discover CXF endpoints and vice
versa. Then there's being able to put Camel inside CXF so that the
JAX-WS client will invoke Camel to do the routing etc


Thoughts and feedback most welcome - also any help getting Camel-CXF
working would be good too :)

-- 

James
-------
http://radio.weblogs.com/0112098/

Re: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by James Strachan <ja...@gmail.com>.
On 3/24/07, Dan Diephouse <da...@envoisolutions.com> wrote:
> Hiya James,
>
> This is very cool. I like the predicate/processor API a lot.

Thanks. FWIW we've nice scripting and XPath support now too...

from(someURI).filter(groovy("foo.bar.any { |i| i.cheese == 'edam'
}")).to(anotherURI).



> Can you explain more what you mean by "I'm just not sure yet in the
> CxfEndpoint how to bind inbound exchanges to the CXF bus and back again
> nicely".

I know the Bus API pretty well; I just don't know the internals of CXF
well enough yet to figure out how to wire Camel and CXF together
nicely. (I've bridged the Exchange/Message classes fine, its the
Channel/Service/Transport parts I've not yet figured out). More in
reply to Jervis's reply later...

Am thinking things we could do are...

* package up Camel as a transport in CXF (then CXF can reuse all the
various Camel transports and Camel can reuse CXF as a nice JAX-WS
typesafe-front end to Camel)
* allow Camel to invoke CXF services (for deploying JAX-WS services
inside Camel and using Camel to route between service implementations)


> Maybe part of the problem is message representation. What do we think of
> creating an XmlMessage which standardizes on using a Source object. Then
> people can write processors which can work for most XML things. CxfMessage
> could then extend XmlMessage.

Yeah; though I do quite like the CXF API where you ask for the body by
class; say as a DOM or Source and it does the right thing. The problem
with XML is that there's so many damn APIs and ways of working with
it...

-- 

James
-------
http://radio.weblogs.com/0112098/

Re: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by Dan Diephouse <da...@envoisolutions.com>.
Hiya James,

This is very cool. I like the predicate/processor API a lot.

Can you explain more what you mean by "I'm just not sure yet in the
CxfEndpoint how to bind inbound exchanges to the CXF bus and back again
nicely".

Maybe part of the problem is message representation. What do we think of
creating an XmlMessage which standardizes on using a Source object. Then
people can write processors which can work for most XML things. CxfMessage
could then extend XmlMessage.

- Dan


>
> Sorry to hijack this thread; a bit of background first then I'll get
> more on topic...
>
> On the ActiveMQ and ServiceMix projects we've wanted a simple POJO
> router for a while thats
>
> * Apache Licensed
> * small & simple with minimal dependencies (just commons-logging)
> * allows routes to be defined easily in Java code or using Spring XML
> * can work with any of the various messaging models and APIs from
> HTTP, JMS, JBI, CXF, JAX-WS, MINA etc
>
> A little experimental library soon turned into a fairly full featured
> router very quickly. The documentation is still quite sparse, but let
> me introduce you to Apache Camel...
> http://activemq.apache.org/camel/
>
> Here's a quick example to give you the idea...
> http://activemq.apache.org/camel/routes.html
>
> We've been documenting how the Enterprise Integration Patterns can be
> implemented using Camel
> http://activemq.apache.org/camel/enterprise-integration-patterns.html
>
> Here's a quick overview of the architecture (we'll document this way
> better soon)
> http://activemq.apache.org/camel/architecture.html
>
>
> One of the interesting things about Camel is it can work with any
> underlying protocol using a small & simple API (similar to a
> simplification & generalization of both CXF Bus API and JBI).  Not
> only that, thanks to generics and covariant return types we can work
> explicitly with specific protocols when required in a nice typesafe
> manner to avoid leaky abstractions.
>
> e.g.
>
> // A JMS specfic processor
> class Foo implements Processor<JmsExchange> {
>   public void onMessage(JmsExchange exchange) {
>
>     // lets do some direct JMS stuff..
>     javax.jms.Message message = exchange.getInMessage();
>   }
> }
>
> So we could easily route from JMS to CXF to JBI and into MINA say.
>
> Enough of all that, lets show an example thats more releative to CXF...
>
> RouteBuilder<Exchange> builder = new RouteBuilder<Exchange>() {
>     public void configure() {
>
>         // a declarative routing rule example
>         from("cxf:myservice").choice()
>                 .when(version().isEqualTo("1.2")).to("cxf:myservice1.2")
>                 .when(xpath("/foo/bar[@cheese =
> 'edam')).to("cxf:myOtherService")
>                 .otherwise().to("jms:Error.Queue");
>     }
> };
>
> In this particular case we're using a custom expression version()
> which could be any old Expression<Exchange> implementation.
>
>
> I think Camel could be useful for arbitrary declarative routing and
> mediation rules in CXF. I've taken an early stab at supporting CXF Bus
> API in Camel...
>
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-cxf/
>
> I've got the main parts done (the exchange & message pieces), I'm just
> not sure yet in the CxfEndpoint how to bind inbound exchanges to the
> CXF bus and back again nicely. Also it'd be nice to resolve URI
> endpoints in Camel nicely to auto-discover CXF endpoints and vice
> versa. Then there's being able to put Camel inside CXF so that the
> JAX-WS client will invoke Camel to do the routing etc
>
>
> Thoughts and feedback most welcome - also any help getting Camel-CXF
> working would be good too :)
>
> --
>
> James
> -------
> http://radio.weblogs.com/0112098/
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by James Strachan <ja...@gmail.com>.
On 3/31/07, Dan Diephouse <da...@envoisolutions.com> wrote:
> On 3/30/07, James Strachan <ja...@gmail.com> wrote:
>
> >
> > I have found the use of CXF Exchange / Message a bit confusing. I
> > looked at different test cases and they seem to use the
> > Exchange/Message in different ways; e.g. some test cases only use the
> > Exchange.getInMessage () and put an InputStream and OutputStream in
> > there then ignoring the out message. Then at some point  when sending
> > a message back into a backConduit an InputStream can get morphed into
> > a PipedInputStream.
>
>
>
> Also it looks strange that a reply can be sent to a back channel, yet
> > after the send, the inbound message's input/ouptut streams are
> > processed some more; from someone with a JMS / JBI background this is
> > very confusing, as send() usually implies the message is ready to be
> > sent, not that the inbound processing hasn't even started yet :).
>
>
> I think we should probably rename send() to open() as thats what it really
> does.

Good idea. Any of open/start/begin would be good.


> Also
> > replies are often sent back, using the inbound message rather than the
> > exchange.getOutMessage().
>
>
> Maybe you are seeing something like this and being confused:
>
> Conduit backChannel = d.getBackChannel(inMsg, null, null);
> backChannel.send(outMsg);
> backChannel.close();
>
> the getBackChannel() selects the appropriate back channel for you using the
> parameters you supply to the method - like the input message. In some cases
> this will be the synchronous http response channel (i.e.
> Destination.getBackChannel()). In some cases this will be a new Conduit
> entirely.

No, it was stuff like this (from LocalTransportFactoryTest)


static class EchoObserver implements MessageObserver {

    public void onMessage(Message message) {
        try {
            Conduit backChannel =
message.getDestination().getBackChannel(message, null, null);
            message.remove(LocalConduit.DIRECT_DISPATCH);

            backChannel.send(message);

            OutputStream out = message.getContent(OutputStream.class);
            assertNotNull(out);
            InputStream in = message.getContent(InputStream.class);
            assertNotNull(in);

            copy(in, out, 1024);

            out.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


> So I've found it a tad complex trying to figure out what is a well
> > behaved connector to CXF Bus API meant to do? I've noodled around the
> > wiki but things do still seem a bit confusing; I wonder is there some
> > kinda canonical test case somewhere that shows what a well behaved
> > client and service of the Bus API is?
>
>
> Maybe check out the ObjectBindingTest that I just committed? I tried to make
> things a little more clear in there about how the server and client sides
> work.

Great thanks!


> I wonder could anyone answer the following questions; it'd certainly
> > be good to pop the answers in a wiki page somewhere to try avoid
> > others getting as confused as I've been lately...
> >
> > * what generally should be in the exchange/in/out messages in terms of
> > headers and body types for a well behaved client & service. (e.g.
> > InputStream seems common in the inMessage right? How about the
> > output?)
>
>
> It is up to the transport to select the reperesentation. When you're sending
> a message via most Conduits, Conduit.send() creates an outputstream which
> you can write to. Conduit.close() then closes this output stream.
> Destinations will typically create an InputStream and set them on the
> incoming message.
>
> The big exception to this is the local transport. The LocalTransport now
> supports a DIRECT_DISPATCH flag which just copies the content from one
> message to another. SO when you send a message, it will create a copy of
> that Message and send the Copy to the receiving Destination.
>
> * whats the lifecycle between sending messages and the use of the
> > streams. e.g. it looks like a service can send a reply before its even
> > started to read the input right? Is it meant to send to the back
> > channel first, then start reading the OutputStream thats put in the
> > in/out message?
>
>
> On the input side you can read right away.
>
> On the output side, an OutpuStream is created when you call
> Conduit.send(message)
> typically. This stream is then closed when you call Conduit.close(message).
> The OutputStream is available via message.getContent(OutputStream.class);
>
> If so where's the proper place to find the
> > OutputStream; the outMessage or inMessage?
>
>
> The out message.
>
>
> * should a service send the outMessage into the Conduit or the inMessage?
>
>
> Hopefully my snippet above helps explain it better.

Great thanks for the clarifications!


-- 

James
-------
http://radio.weblogs.com/0112098/

Re: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/30/07, James Strachan <ja...@gmail.com> wrote:

>
> I have found the use of CXF Exchange / Message a bit confusing. I
> looked at different test cases and they seem to use the
> Exchange/Message in different ways; e.g. some test cases only use the
> Exchange.getInMessage () and put an InputStream and OutputStream in
> there then ignoring the out message. Then at some point  when sending
> a message back into a backConduit an InputStream can get morphed into
> a PipedInputStream.



Also it looks strange that a reply can be sent to a back channel, yet
> after the send, the inbound message's input/ouptut streams are
> processed some more; from someone with a JMS / JBI background this is
> very confusing, as send() usually implies the message is ready to be
> sent, not that the inbound processing hasn't even started yet :).


I think we should probably rename send() to open() as thats what it really
does.

Also
> replies are often sent back, using the inbound message rather than the
> exchange.getOutMessage().


Maybe you are seeing something like this and being confused:

Conduit backChannel = d.getBackChannel(inMsg, null, null);
backChannel.send(outMsg);
backChannel.close();

the getBackChannel() selects the appropriate back channel for you using the
parameters you supply to the method - like the input message. In some cases
this will be the synchronous http response channel (i.e.
Destination.getBackChannel()). In some cases this will be a new Conduit
entirely.


So I've found it a tad complex trying to figure out what is a well
> behaved connector to CXF Bus API meant to do? I've noodled around the
> wiki but things do still seem a bit confusing; I wonder is there some
> kinda canonical test case somewhere that shows what a well behaved
> client and service of the Bus API is?


Maybe check out the ObjectBindingTest that I just committed? I tried to make
things a little more clear in there about how the server and client sides
work.

I wonder could anyone answer the following questions; it'd certainly
> be good to pop the answers in a wiki page somewhere to try avoid
> others getting as confused as I've been lately...
>
> * what generally should be in the exchange/in/out messages in terms of
> headers and body types for a well behaved client & service. (e.g.
> InputStream seems common in the inMessage right? How about the
> output?)


It is up to the transport to select the reperesentation. When you're sending
a message via most Conduits, Conduit.send() creates an outputstream which
you can write to. Conduit.close() then closes this output stream.
Destinations will typically create an InputStream and set them on the
incoming message.

The big exception to this is the local transport. The LocalTransport now
supports a DIRECT_DISPATCH flag which just copies the content from one
message to another. SO when you send a message, it will create a copy of
that Message and send the Copy to the receiving Destination.

* whats the lifecycle between sending messages and the use of the
> streams. e.g. it looks like a service can send a reply before its even
> started to read the input right? Is it meant to send to the back
> channel first, then start reading the OutputStream thats put in the
> in/out message?


On the input side you can read right away.

On the output side, an OutpuStream is created when you call
Conduit.send(message)
typically. This stream is then closed when you call Conduit.close(message).
The OutputStream is available via message.getContent(OutputStream.class);

If so where's the proper place to find the
> OutputStream; the outMessage or inMessage?


The out message.


* should a service send the outMessage into the Conduit or the inMessage?


Hopefully my snippet above helps explain it better.


Regards,

- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by James Strachan <ja...@gmail.com>.
On 3/26/07, Liu, Jervis <jl...@iona.com> wrote:
> Hi James, thanks for the info, very interesting project, anxious to see a CXFRouteTest sample running in Camel soon :-),

Me too! :)

I've got a real basic CxfTest working now that fires off a Camel
exchange and uses CXF to process  the endpoint; its a bit of a crappy
example, but its a start...



>  do let us know if there is anything we can help out. Regarding "Also it'd be nice to resolve URI endpoints in Camel nicely to auto-discover CXF endpoints and vice versa", would you be able to use a code snippet like below?
>
>         Bus bus = CXFBusFactory.getDefaultBus();
>         ServerRegistry serverRegistry = bus.getExtension(ServerRegistry.class);
>         List<Server> servers = serverRegistry.getServers();
>
>         Server targetServer = null;
>         for (Server server : servers) {
>             targetServer = server;
>             String address = server.getEndpoint().getEndpointInfo().getAddress();
>            ....
>         }

Awesome! That really helped me get started, thanks!

After a quick chat on IRC DanD suggested using a LocalTransport /
LocalConduit / LocalDestination for interactions with CXF from inside
Camel. So I've hacked up an initial version of CxfComponent /
CxfEndpoint using this approach. It seems to be working ok though I'm
still a little unclear on a few things (more below...).

I've hacked a very rough implementation of a CXF Transport too; trying
to basically port the JMS transport to Camel - though I don't quite
undersand the code well enough yet so it needs some serious work :).


I have found the use of CXF Exchange / Message a bit confusing. I
looked at different test cases and they seem to use the
Exchange/Message in different ways; e.g. some test cases only use the
Exchange.getInMessage() and put an InputStream and OutputStream in
there then ignoring the out message. Then at some point  when sending
a message back into a backConduit an InputStream can get morphed into
a PipedInputStream.

Also it looks strange that a reply can be sent to a back channel, yet
after the send, the inbound message's input/ouptut streams are
processed some more; from someone with a JMS / JBI background this is
very confusing, as send() usually implies the message is ready to be
sent, not that the inbound processing hasn't even started yet :). Also
replies are often sent back, using the inbound message rather than the
exchange.getOutMessage().

So I've found it a tad complex trying to figure out what is a well
behaved connector to CXF Bus API meant to do? I've noodled around the
wiki but things do still seem a bit confusing; I wonder is there some
kinda canonical test case somewhere that shows what a well behaved
client and service of the Bus API is?

I wonder could anyone answer the following questions; it'd certainly
be good to pop the answers in a wiki page somewhere to try avoid
others getting as confused as I've been lately...

* what generally should be in the exchange/in/out messages in terms of
headers and body types for a well behaved client & service. (e.g.
InputStream seems common in the inMessage right? How about the
output?)

* whats the lifecycle between sending messages and the use of the
streams. e.g. it looks like a service can send a reply before its even
started to read the input right? Is it meant to send to the back
channel first, then start reading the OutputStream thats put in the
in/out message? If so where's the proper place to find the
OutputStream; the outMessage or inMessage?

* should a service send the outMessage into the Conduit or the inMessage?


> I also saw your comments in org.apache.camel.component.cxf.CxfBinding, this message representation problem is a hard one. The "CXFBinding", as its name suggested, is a very vague concept, as in CXF, we can support many different transports and bindings, for example SOAP binding, XML binding or CDR (CORBA).


Yeah I hear you  :). To be honest I don't like the name I chose of
CxfBinding; its kinda the 'CxfMarshaller' (figuring out how to convert
from a Camel exchange to a CXF exchange and vice versea), though I'm
not overly keen on the word "Marshaller" as there's no consistent
spelling of it so code often uses both spellings :). Anyone got any
better ideas? Maybe CxfAdapter is better? (though thats another word
with 2 spellings....)



>  In the latter case, obviously using an XML Source object wont work. In CXF we have a concept that built upon an underlying format of inputStream (lets take the inbound as an example),  we may have many different representations of the incoming message, it can be an XMLInputStream, a SAAJ message or Java objects.


Yeah, I understand. Unlike JBI which assumes Source objects, Camel is
very flexible, allowing endpoints to use any Java representations.
Then there's a type coercion helper library so folks can switch from
InputStream <-> Reader <-> String <-> Document <-> Source <-> POJO
based on what they need etc.
http://activemq.apache.org/camel/type-converter.html


> Interceptors that belong to different phases can pick the representation of their interest to work with, of course, they have to know what format they can expect by calling mesage.getContent(...). In the case of org.apache.camel.component.cxf.CxfBinding, might be a good idea to have an abstract CxfBinding class, then several extensions such as CXFSoapBinding, CXFXMLBinding, CXFCORBABinding etc.


Agreed. The idea behind the CxfBinding class was to be the
plugin-strategy for figuring out how to go to/from Camel <-> CXF as
you suggest. Then using some configuration mechanism (or URI format)
we can choose the right binding/adapter/marshaller approach



>  Another thought is that it is likely we may only want to use a stream format in the router, for example, we only scan the soap header or name space, once we find the info we will stop any further scanning and redirect the request. In this case, using a Stax based API presumably will have better performance than transforming the whole input into XML objects.


Agreed. Hopefully the interceptors/processors can choose what types
they want things to be; then if need be we can add further
interceptors / transformers to make things efficient to minimise
things like multiple XML parsers etc.

I've not thought too much about it yet, but we may want to include
Camel routing & mediation rules as an interceptor as well as a
transport & Service...


Thanks for your great feedback!

-- 

James
-------
http://radio.weblogs.com/0112098/

RE: Introducing Apache Camel (was Re: The implementation of a simple service routing. WAS: RE: Release Update)

Posted by "Liu, Jervis" <jl...@iona.com>.
Hi James, thanks for the info, very interesting project, anxious to see a CXFRouteTest sample running in Camel soon :-), do let us know if there is anything we can help out. Regarding "Also it'd be nice to resolve URI endpoints in Camel nicely to auto-discover CXF endpoints and vice versa", would you be able to use a code snippet like below?

        Bus bus = CXFBusFactory.getDefaultBus();
        ServerRegistry serverRegistry = bus.getExtension(ServerRegistry.class);
        List<Server> servers = serverRegistry.getServers();

        Server targetServer = null;
        for (Server server : servers) {
            targetServer = server;
            String address = server.getEndpoint().getEndpointInfo().getAddress();
           ....
        }

I also saw your comments in org.apache.camel.component.cxf.CxfBinding, this message representation problem is a hard one. The "CXFBinding", as its name suggested, is a very vague concept, as in CXF, we can support many different transports and bindings, for example SOAP binding, XML binding or CDR (CORBA). In the latter case, obviously using an XML Source object wont work. In CXF we have a concept that built upon an underlying format of inputStream (lets take the inbound as an example),  we may have many different representations of the incoming message, it can be an XMLInputStream, a SAAJ message or Java objects. Interceptors that belong to different phases can pick the representation of their interest to work with, of course, they have to know what format they can expect by calling mesage.getContent(...). In the case of org.apache.camel.component.cxf.CxfBinding, might be a good idea to have an abstract CxfBinding class, then several extensions such as CXFSoapBinding, CXFXMLBinding, CXFCORBABinding etc. Another thought is that it is likely we may only want to use a stream format in the router, for example, we only scan the soap header or name space, once we find the info we will stop any further scanning and redirect the request. In this case, using a Stax based API presumably will have better performance than transforming the whole input into XML objects. 

Cheers,
Jervis

> -----Original Message-----
> From: James Strachan [mailto:james.strachan@gmail.com]
> Sent: 2007?3?23? 23:09
> To: cxf-dev@incubator.apache.org
> Subject: Introducing Apache Camel (was Re: The implementation 
> of a simple service routing. WAS: RE: Release Update)
> 
> 
> On 3/23/07, Liu, Jervis <jl...@iona.com> wrote:
> > Hi, I've been experimenting a bit on the service routing 
> lately, the result has been put on the wiki: 
> http://cwiki.apache.org/confluence/display/CXF20DOC/Service+Ro
> uting. So it works ((I will check in a system test shortly), 
> my main concern though, is that this implementation does not 
> seem to be very "simple", it does require a fair amount of 
> knowledge of CXF internal. Not sure if it is appropriate to 
> expose this to CXF userland. Anyway, I am open to any 
> comments&suggestions.
> >
> > Thanks,
> > Jervis
> >
> > > -----Original Message-----
> > > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > > Sent: 2007?3?17? 3:32
> > > To: cxf-dev@incubator.apache.org
> > > Subject: Re: Release Update
> > >
> > >
> > > On 3/15/07, Liu, Jervis <jl...@iona.com> wrote:
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > > > > Sent: 2007?3?15? 21:44
> > > > > To: cxf-dev@incubator.apache.org
> > > > > Subject: Re: Release Update
> > > > >
> > > > >
> > > > > Hi Jervis,
> > > > >
> > > > > I wanted to ensure that we can setup an endpoint on a URL
> > > and route to
> > > > > different services based on headers (such as ws-a) or other
> > > > > logic.  I made a
> > > > > series of proposals about how to do this a while back, but I
> > > > > don't think we
> > > > > ever came to any concrete conclusion.
> > > > >
> > > > Ok, I see what you mean. I believe you are referring to
> > > this proposal [1].
> > > > One thing I have not figured out from the proposal yet is
> > > how we know the
> > > > addresses of services to which the routing service is about
> > > to redirect?
> > > > Through some kind of registries or a configuration loaded
> > > from a separate
> > > > file or a WSDL extension.? Once this kind of discussion
> > > gets started, I do
> > > > not see how it can end by the end of this release. Service
> > > routing is a huge
> > > > topic anyway. However we will have much less to worry about
> > > if we are not
> > > > after a complete resolution of service routing. For
> > > example, if we only
> > > > support the routing among different endpoints within the
> > > same Destination,
> > > > would this feature be considered helpful for some certain
> > > use cases? Reading
> > > > your proposal, I believe this is also what you want to do,
> > > start from sth
> > > > simple first. If this is the case, I am ready to get my
> > > hands dirty now.
> > > >
> > > > BTW, I am in a traveling at the moment, I may not respond
> > > in time until I
> > > > get back to office next Tuesday.
> > > >
> > > > [1].
> > > >
> > > http://mail-archives.apache.org/mod_mbox/incubator-cxf-dev/200
> > 
> 612.mbox/%3c7b774c950612021343x513c2783o128a032ba93923bb@mail.
> gmail.com%3e
> >
> >
> >
> > Yes, I'm really just concerned about the simple case. 
> Namely being able to
> > create some type of routing endpoint which routes to other types of
> > services. My main use cases is versioning of services. 
> Ideally many services
> > can share the same URL and I can route by headers or the 
> namespace of the
> > body part.
> >
> > Regarding how to know what services to route to - I think 
> its up to the user
> > to write that code. I was kind of envisioning that it'd be 
> an interceptor
> > that a user writes. We could build something more formal 
> like a registry,
> > but we would need something low level first :-)
> 
> Sorry to hijack this thread; a bit of background first then I'll get
> more on topic...
> 
> On the ActiveMQ and ServiceMix projects we've wanted a simple POJO
> router for a while thats
> 
> * Apache Licensed
> * small & simple with minimal dependencies (just commons-logging)
> * allows routes to be defined easily in Java code or using Spring XML
> * can work with any of the various messaging models and APIs from
> HTTP, JMS, JBI, CXF, JAX-WS, MINA etc
> 
> A little experimental library soon turned into a fairly full featured
> router very quickly. The documentation is still quite sparse, but let
> me introduce you to Apache Camel...
> http://activemq.apache.org/camel/
> 
> Here's a quick example to give you the idea...
> http://activemq.apache.org/camel/routes.html
> 
> We've been documenting how the Enterprise Integration Patterns can be
> implemented using Camel
> http://activemq.apache.org/camel/enterprise-integration-patterns.html
> 
> Here's a quick overview of the architecture (we'll document this way
> better soon)
> http://activemq.apache.org/camel/architecture.html
> 
> 
> One of the interesting things about Camel is it can work with any
> underlying protocol using a small & simple API (similar to a
> simplification & generalization of both CXF Bus API and JBI).  Not
> only that, thanks to generics and covariant return types we can work
> explicitly with specific protocols when required in a nice typesafe
> manner to avoid leaky abstractions.
> 
> e.g.
> 
> // A JMS specfic processor
> class Foo implements Processor<JmsExchange> {
>   public void onMessage(JmsExchange exchange) {
> 
>     // lets do some direct JMS stuff..
>     javax.jms.Message message = exchange.getInMessage();
>   }
> }
> 
> So we could easily route from JMS to CXF to JBI and into MINA say.
> 
> Enough of all that, lets show an example thats more releative 
> to CXF...
> 
> RouteBuilder<Exchange> builder = new RouteBuilder<Exchange>() {
>     public void configure() {
> 
>         // a declarative routing rule example
>         from("cxf:myservice").choice()
>                 
> .when(version().isEqualTo("1.2")).to("cxf:myservice1.2")
>                 .when(xpath("/foo/bar[@cheese =
> 'edam')).to("cxf:myOtherService")
>                 .otherwise().to("jms:Error.Queue");
>     }
> };
> 
> In this particular case we're using a custom expression version()
> which could be any old Expression<Exchange> implementation.
> 
> 
> I think Camel could be useful for arbitrary declarative routing and
> mediation rules in CXF. I've taken an early stab at supporting CXF Bus
> API in Camel...
> 
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-cxf/
> 
> I've got the main parts done (the exchange & message pieces), I'm just
> not sure yet in the CxfEndpoint how to bind inbound exchanges to the
> CXF bus and back again nicely. Also it'd be nice to resolve URI
> endpoints in Camel nicely to auto-discover CXF endpoints and vice
> versa. Then there's being able to put Camel inside CXF so that the
> JAX-WS client will invoke Camel to do the routing etc
> 
> 
> Thoughts and feedback most welcome - also any help getting Camel-CXF
> working would be good too :)
> 
> -- 
> 
> James
> -------
> http://radio.weblogs.com/0112098/
>