cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bharath Gargesh <bharath.garg...@hp.com>
Subject Re: Writing my own transport
Date Thu, 07 May 2009 17:38:45 GMT

Hi Dan,

Long story short, I got this working yesterday.

This concept of Local Transport in CXF is very useful for custom transports. 
I think there should be more documentation on how to use this.
I also think that Interceptors is another very useful thing for customizing,
more documentation would be very helpful.

I had the following working before,
LocalConduit.prepare() sets up the Message's OutputStream (this is on the
server side).
LocalConduit's MessageObserver gets the response from the Endpoint object
reference.

On the Client Side,
I could intercept the messages from the Service's Client side proxy/Dispatch
in the LocalDestination's MessageObserver.

The problem was this, How do I send back the response from the
LocalDestination's MessageObserver, back to the Caller of the Client Proxy
or Dispatch.invoke() ?
After a few days of trial and error I found out, that I can get the
OutputStream of a Message in the Destination's Observer as follows:
Conduit c = message.getDestination().getBackChannel(message, null, null);
Then it was fairly simple as before, call the Conduit.prepare(Message) to
get the OutputStream, write to this and this will automatically send the
response back to the Caller of the Dispatch.invoke() or ClientProxy.


Thank you very much for following this up. Thanks for all the help.

Regards
Bharath.



dkulp wrote:
> 
> 
> Bharath,
> 
> Did you get this working?
> 
> Basically, the Conduit extends Observable and the client registers a 
> MessageObserver with the conduit via the setMessageObserver call.   On the 
> incoming message, you would need to setup a Message and just call the 
> onMessage call of that observer.    That should be it.
> 
> Basically, in code:
> 
> Message inMessage = new MessageImpl();
> exchange.setInMessage(inMessage);
> 
> //set things like protocol headers and stuff here
> ....
>  inMessage.setContent(InputStream.class, is);
> 
> incomingObserver.onMessage(inMessage);
> 
> 
> 
> Dan
> 
> 
> On Sat April 25 2009 2:09:44 am Bharath Gargesh wrote:
>> Hi Dan and Ulhas,
>>
>> Thanks to you two, now I can publish messages to Local Transport and
>> intercept them.
>>
>> Now I am able to intercept the messages in the MessageObservers of the
>> LocalDestination and the LocalConduit.
>>
>> I work on a platform which provides Java API for IPC. The API allows
>> transfer of bytes from one process to another.
>> My plan is as follows:
>>
>> 1.) Publish a JAX-WS endpoint on a local Transport, Get the LocalConduit
>> and register a MessageObserver in it. Wait for IPC messages here, when
>> any
>> message is got, convert this to SOAP message and send it to the Local
>> JAX-WS Endpoint Impl, get the response and Reply back.
>>
>> 2.) Now the Client (JAX-WS Client). Get the LocalDestination (register a
>> dummy local Endpoint here) and register the MessageObserver. Intercept
>> the
>> messages from the Client here and post the messages to the Step 1.)
>> through
>> IPC. I can get the response from the JAX-WS Service.
>>
>> But now I am stuck here. How do I reply the response to the caller/JAX-WS
>> Client.
>>
>> Where should I look into (Interceptors and Phases ?). Kindly provide a
>> brief outline of how do I acheive the above. Or simply put, How can I
>> propagate the message from LocalDestination's MessageObserver back to the
>> caller ?
>>
>> Kindly reply.
>>
>> Regards
>> Bharath
>>
>> dkulp wrote:
>> > Bharath,
>> >
>> > It's relatively simple.....
>> >
>> > Service service = new Service(seviceName);
>> > service.addPort(portName,
>> >           "http://schemas.xmlsoap.org/soap/",
>> >           "local://localhost:9090/hello");
>> > HelloInterface proxy = service.getPort(portName, HelloInterface.class);
>> >
>> > Basically, use the same URL as you did for the server side publish.
>> >
>> >
>> > Dan
>> >
>> > On Fri April 24 2009 6:29:07 am Bharath Gargesh wrote:
>> >> Hi Dan,
>> >> I wanted to write my own transport, but then I saw your reply to this
>> >> thread and found out a way to do this.
>> >> But only that I was able to go half way through.
>> >> On the Server side I did the following:
>> >> 1.) Develop a JAX-WS and publish it to a local address.
>> >> 2.) Got a handle to the LocalConduit through the Default Bus
>> >> 3.) Registered a Listener to the Conduit.
>> >> 4.) Prepare a SOAP Message for calling the JAX-WS, publish it
>> >>      to the Conduit.close() and the reply SOAP Message from the JAX-WS
>> >>      was got in the Listener.
>> >>
>> >> This is absolutely fine, the only thing that I need to do is,
>> construct
>> >> a SOAP Message to invoke the JAX-WS.
>> >> But I want to use the JAX-WS Client generated to be able to publish
>> the
>> >> message to the Local transport.
>> >> How can I force/use the JAX-WS client to put the message into the
>> Local
>> >> transport ?
>> >>
>> >> Can you please give me an Idea on how to do this for the JAX-WS client
>> >> too.
>> >>
>> >> Regards
>> >> Bharath
>> >>
>> >> dkulp wrote:
>> >> > Marcel,
>> >> >
>> >> > You can actually use the Local transport for this as well.   We have
>> >> > several tests that do this exact thing.
>> >> >
>> >> > We have a TestUtilities class:
>> >>
>> >>
>> http://svn.apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apac
>> >>h
>> >>
>> >> >e/cxf/test/TestUtilities.java Look in the "invokeBytes" message which
>> >> > could show you how to invoke a "local" service using raw data.   The
>> >> > invokeBytes takes a string message in and returns a byte[], but it
>> >>
>> >> would
>> >>
>> >> > be very easy to replace that with streams or a DOM or something
>> >>
>> >> similar.
>> >>
>> >> > Dan
>> >> >
>> >> > On May 26, 2008, at 8:09 AM, Heemskerk, Marcel (M.) wrote:
>> >> >> Hello Dan and CXF,
>> >> >>
>> >> >> I've been looking in the documentation and still it's quite fuzy
>> for
>> >> >> me.
>> >> >>
>> >> >> What i need is the following:
>> >> >>
>> >> >> We work WSDL first, so i have to stick to a certain XML format.
>> From
>> >> >> this i generate an HTTP service implementation. It contains (for
>> >> >> example) the following pojo:
>> >>
>> >>
>> ------------------------------------------------------------------------
>> >>
>> >> >> --------
>> >> >> package com.sample;
>> >> >> import javax.jws.WebService;
>> >> >>
>> >> >> @WebService(endpointInterface = "com.sample.WSInterface",
>> >> >> targetNamespace = "http://com.sample/Calculator")
>> >> >> public class Calculator {
>> >> >> 	public CalculatorResult calculate(CalculatorQuestion q) {
>> >> >> 		return new CalculatorResult(q);
>> >> >> 	}
>> >> >> }
>> >>
>> >>
>> ------------------------------------------------------------------------
>> >>
>> >> >> --------
>> >> >>
>> >> >> This is deployed as web service:
>> >>
>> >>
>> ------------------------------------------------------------------------
>> >>
>> >> >> --------
>> >> >> <bean id="calculatorBean" class="com.sample.Calculator"/>
>> >> >>
>> >> >> <jaxws:endpoint
>> >> >> 	  id="calculatorService"
>> >> >> 	  implementor="#calculatorBean"
>> >> >> 	  address="/"
>> >> >> 	  wsdlLocation="/WEB-INF/wsdl/calculator.wsdl"
>> >> >> 	  serviceName="tns:calc"
>> >> >> 	  xmlns:tns="http://com.sample/Calculator"/>
>> >>
>> >>
>> ------------------------------------------------------------------------
>> >>
>> >> >> --------
>> >> >>
>> >> >>
>> >> >> What i want to do, is call the service through the JVM (thus NOT
>> >> >> through
>> >> >> HTTP), with plain SOAP XML as input and plain XML as output,
>> >> >> including custom SOAP Headers, WS-Security headers, and what not.
>> >> >>
>> >> >> If i use local transport i am stuck with the "Java interface" with
>> >> >> CalculatorQuestion  and CalculatorResult.
>> >> >>
>> >> >> Which are the absolute minimum classes i need to implement?
>> >> >>
>> >> >>
>> >> >> Thanks a lot for your info!
>> >> >>
>> >> >> - Marcel
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> -----Oorspronkelijk bericht-----
>> >> >> Van: Daniel Kulp [mailto:dkulp@apache.org]
>> >> >> Verzonden: woensdag 7 mei 2008 6:09
>> >> >> Aan: dev@cxf.apache.org
>> >> >> Onderwerp: Re: Writing my own transport
>> >> >>
>> >> >>
>> >> >>
>> >> >> Depending on what you need to do, you may not need all of the below
>> >> >> classes.
>> >> >>
>> >> >> For example, the CachedXXXputStream stuff may not be necessary
>> >> >> depending on your protocol and current stream implementations.
>> >> >> Actually, in most cases, you DON'T want to use that.   Instead,
use
>> a
>> >> >> subclass of the AbstractWrappedOutputStream or your own stuff.
>> >> >>
>> >> >> The TransportFactory is technically not required either.   It
>> depends
>> >> >> on what you need to do.
>> >> >>
>> >> >> If you only need to write a client to talk to an existing service,
>> >> >> you need a Conduit and a ConduitInitiator.
>> >> >>
>> >> >> Likewise, if you need to write a server only, you just need a
>> >> >> Destination and DestinationFactory.   The TransportFactory is
>> >> >> basically a convienience if you need both as it can be the
>> >> >> ConduitInitiator and the DestinationFactory in on.
>> >> >>
>> >> >>
>> >> >> Most of the "Logic" occurs in the Conduit/Destination objects.
>> >> >> Generally, the Conduit.prepare adds an OutputStream to the method
>> >> >> that does a couple things:
>> >> >>
>> >> >> 1) On the first write, it will do whatever header processing stuff
>> is
>> >> >> needed.  For HTTP, it sets the HTTP headers.
>> >> >>
>> >> >> 2) On the close, it can do one of:
>> >> >>     a) wait for the response and call the listener directly.  The
>> >> >> http conduit does this.  It's generally the faster way to do it
in
>> >> >> most cases.
>> >> >>     b) Just send the message if there is some other asyncronous
way
>> >> >> that the response will come in and have the message listener
>> called.
>> >> >> The local transport does this.
>> >> >>
>> >> >> The AbstractWrappedOutputStream makes some of the above easier
by
>> >> >> providing callbacks for those events, but it can be any stream.
>> >> >>
>> >> >>
>> >> >>
>> >> >> Dan
>> >> >>
>> >> >> On May 6, 2008, at 9:24 PM, Freeman Fang wrote:
>> >> >>> Hi Marcel,
>> >> >>> Assume the transport you want to implement is AAA, basically
you
>> >> >>> need several class as below
>> >> >>>
>> >> >>> AAAConduit extends AbstractConduit,  kinda like  your transport
>> >> >>> client
>> >> >>>
>> >> >>> AAADestination extends AbstractDestination,  your transport
>> >> >>> destination
>> >> >>> AAAConduitOutputStream extends CachedOutputStream, send out
client
>> >> >>> request, you should use your transport api to send out request
in
>> >> >>> this class
>> >> >>> AAADestinationOutputStream extends CachedOutputStream, send
out
>> >> >>> server response, you should use your transport api to send
out
>> >> >>> response in this class
>> >> >>> AAATransportFactory, factory to get Conduit and Destination,
also
>> >> >>> you need a transport_id to distinguash your transport
>> >> >>>
>> >> >>> You can take a look at org.apache.cxf.transport.jbi which should
>> be
>> >> >>> like your scenario
>> >> >>>
>> >> >>> Freeman
>> >> >>>
>> >> >>> Marcel Heemskerk wrote:
>> >> >>>> I have a service 'service1'  listening to HTTP. I would
like be
>> >> >>>> able to make
>> >> >>>> a new transport for this service, so i can use a propietary
>> >> >>>> transport
>> >> >>>> protocol to receive the InputStream and send the OutputStream
to.
>> >> >>>> The
>> >> >>>> received message is SOAP, so i just want to send it into
the CXF
>> >> >>>> marshalling
>> >> >>>> layer to have deserialized to a SOAP header with
>> >> >>>> javax.xml.ws.Holder and
>> >> >>>> SOAP response, etc...
>> >> >>>>
>> >> >>>> It should be simple, because i want to re-use the existing
>> >> >>>> 'service1'
>> >> >>>>
>> >> >>>> binding, JAXB, etc. However, it does not seem obvious.
I've been
>> >> >>>> trying to
>> >> >>>> reverse engineer the JMS transport or HTTP transport but
no luck
>> so
>> >> >>>> far.
>> >> >>>> Could someone point out to me the relevant files or a tutorial
on
>> >> >>>> this
>> >> >>>> matter?
>> >> >>>>
>> >> >>>> Thanks,
>> >> >>>> Marcel
>> >> >>
>> >> >> Daniel Kulp
>> >> >> dkulp@apache.org
>> >> >> http://www.dankulp.com/blog
>> >> >
>> >> > ---
>> >> > Daniel Kulp
>> >> > dkulp@apache.org
>> >> > http://www.dankulp.com/blog
>> >
>> > --
>> > Daniel Kulp
>> > dkulp@apache.org
>> > http://www.dankulp.com/blog
> 
> -- 
> Daniel Kulp
> dkulp@apache.org
> http://www.dankulp.com/blog
> 
> 

-- 
View this message in context: http://www.nabble.com/Writing-my-own-transport-tp17088528p23431787.html
Sent from the cxf-dev mailing list archive at Nabble.com.


Mime
View raw message