You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Christian Schneider <ch...@die-schneider.net> on 2010/01/19 22:53:42 UTC

Easy One way soap services

Hi all,

I am thinking about how to make one way services easier. Currently I 
generate code for the service using cxf codegen and use the camel-cxf 
module to create a client or endpoint that can be routed over jms using 
the camel-jms component. Using CXF for this task is a little overkill as 
very few features of CXF are used and quite a lot of configuration has 
to be done. I wonder if this can be done easier.

I have experimented with a possible solution for the server part. It 
looks like this:
from("jms:myqueue").process(new 
SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");

The idea is that a soap message for the service comes in over jms. The 
soap processor parses the soap xml, strips the Envelope and Body and 
unmarshals the content using JAXB. The processor needs the package name 
of the generated stub code for the service. The advantage over using 
camel-cxf is that there is much less configuration and you do not need 
cxf at runtime (which means much less jars). Additionally the 
serviceHandler bean only needs to have a method with the expected classs 
type as input parameter it does not need to implement a service 
interface. I have added the code of SoapProcessor to the mail as it is 
quite small.

So what do you think? Does it make sense to have such small scale SOAP 
functionality in camel?
I am thinking about turning my Processor into a DataFormat and provide 
marshalling and unmarshalling. Does this make sense or is a processor 
better?

Greetings

Christian

-- 

Christian Schneider
---
http://www.liquid-reality.de

----


import java.io.InputStream;
import java.util.Iterator;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

public class SoapProcessor implements Processor {

	private XPathExpression xpathExpression;
	private Unmarshaller unmarshaller;

	public SoapProcessor(String jaxbPackage) {
		super();
		XPath xpath = XPathFactory.newInstance().newXPath();
		xpath.setNamespaceContext(new SoapNameSpaceContext());
		try {
			xpathExpression = xpath.compile("/soap:Envelope/soap:Body/*");
			JAXBContext jContext = JAXBContext.newInstance(jaxbPackage);
			unmarshaller = jContext.createUnmarshaller();
		} catch (XPathExpressionException e) {
			throw new RuntimeException(e.getMessage(), e);
		} catch (JAXBException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		
	}

	private final class SoapNameSpaceContext implements NamespaceContext {
		private static final String SOAP_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";

		public Iterator<?>  getPrefixes(String namespaceURI) {
			return null;
		}

		public String getPrefix(String namespaceURI) {
			return null;
		}

		public String getNamespaceURI(String prefix) {
			return SOAP_NAMESPACE;
		}
	}

	public void process(Exchange exchange) throws Exception {
		InputStream request = exchange.getIn().getBody(InputStream.class);
		InputSource is = new InputSource(request);
		Element payload = (Element) xpathExpression.evaluate(is, XPathConstants.NODE);
		JAXBElement<?>  el = (JAXBElement<?>) unmarshaller.unmarshal(payload);
		Object o = el.getValue();
		exchange.getIn().setBody(o);
	}

}


Re: Easy One way soap services

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

On Tue, Jan 19, 2010 at 10:53 PM, Christian Schneider
<ch...@die-schneider.net> wrote:
> Hi all,
>
> I am thinking about how to make one way services easier. Currently I
> generate code for the service using cxf codegen and use the camel-cxf module
> to create a client or endpoint that can be routed over jms using the
> camel-jms component. Using CXF for this task is a little overkill as very
> few features of CXF are used and quite a lot of configuration has to be
> done. I wonder if this can be done easier.
>
> I have experimented with a possible solution for the server part. It looks
> like this:
> from("jms:myqueue").process(new
> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>
> The idea is that a soap message for the service comes in over jms. The soap
> processor parses the soap xml, strips the Envelope and Body and unmarshals
> the content using JAXB. The processor needs the package name of the
> generated stub code for the service. The advantage over using camel-cxf is
> that there is much less configuration and you do not need cxf at runtime
> (which means much less jars). Additionally the serviceHandler bean only
> needs to have a method with the expected classs type as input parameter it
> does not need to implement a service interface. I have added the code of
> SoapProcessor to the mail as it is quite small.
>
> So what do you think? Does it make sense to have such small scale SOAP
> functionality in camel?
> I am thinking about turning my Processor into a DataFormat and provide
> marshalling and unmarshalling. Does this make sense or is a processor
> better?
>

Cool stuff. I like anything that can make SOAP simpler.

Actually I wished we had this simple SOAP component out of the box at Camel
http://code.google.com/p/camel-soap/

Maybe your work can evolve into something like that supporting both use-cases?


> Greetings
>
> Christian
>
> --
>
> Christian Schneider
> ---
> http://www.liquid-reality.de
>
> ----
>
>
> import java.io.InputStream;
> import java.util.Iterator;
>
> import javax.xml.bind.JAXBContext;
> import javax.xml.bind.JAXBElement;
> import javax.xml.bind.JAXBException;
> import javax.xml.bind.Unmarshaller;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.xpath.XPath;
> import javax.xml.xpath.XPathConstants;
> import javax.xml.xpath.XPathExpression;
> import javax.xml.xpath.XPathExpressionException;
> import javax.xml.xpath.XPathFactory;
>
> import org.apache.camel.Exchange;
> import org.apache.camel.Processor;
> import org.w3c.dom.Element;
> import org.xml.sax.InputSource;
>
> public class SoapProcessor implements Processor {
>
>        private XPathExpression xpathExpression;
>        private Unmarshaller unmarshaller;
>
>        public SoapProcessor(String jaxbPackage) {
>                super();
>                XPath xpath = XPathFactory.newInstance().newXPath();
>                xpath.setNamespaceContext(new SoapNameSpaceContext());
>                try {
>                        xpathExpression =
> xpath.compile("/soap:Envelope/soap:Body/*");
>                        JAXBContext jContext =
> JAXBContext.newInstance(jaxbPackage);
>                        unmarshaller = jContext.createUnmarshaller();
>                } catch (XPathExpressionException e) {
>                        throw new RuntimeException(e.getMessage(), e);
>                } catch (JAXBException e) {
>                        throw new RuntimeException(e.getMessage(), e);
>                }
>
>        }
>
>        private final class SoapNameSpaceContext implements NamespaceContext
> {
>                private static final String SOAP_NAMESPACE =
> "http://schemas.xmlsoap.org/soap/envelope/";
>
>                public Iterator<?>  getPrefixes(String namespaceURI) {
>                        return null;
>                }
>
>                public String getPrefix(String namespaceURI) {
>                        return null;
>                }
>
>                public String getNamespaceURI(String prefix) {
>                        return SOAP_NAMESPACE;
>                }
>        }
>
>        public void process(Exchange exchange) throws Exception {
>                InputStream request =
> exchange.getIn().getBody(InputStream.class);
>                InputSource is = new InputSource(request);
>                Element payload = (Element) xpathExpression.evaluate(is,
> XPathConstants.NODE);
>                JAXBElement<?>  el = (JAXBElement<?>)
> unmarshaller.unmarshal(payload);
>                Object o = el.getValue();
>                exchange.getIn().setBody(o);
>        }
>
> }
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Easy One way soap services

Posted by Claus Ibsen <cl...@gmail.com>.
You could also create a SOAPDataFormat which extends JAXBDataFormat
which I think would be a good choice.
Then the JAXBDataFormat is still pure and clean in terms of JAXB.

And the SOAPDataFormat can over time have additional SOAP related stuff in it.

The code can still be in camel-jaxb if you do not bring in any new
.jar dependencies.
If you can foresee this then a new camel-soap would be a good idea,
which deps on camel-jaxb.


On Thu, Jan 21, 2010 at 8:47 AM, Willem Jiang <wi...@gmail.com> wrote:
> Hi Christian,
>
> I think it dependents what you want to do for further enhancement of the
> your current solution. If you just want to add or strip the SOAP , an option
> of the JAXB DataFormat could be enough.
> If you want to do more enhancement, you'd better create a SOAP DataFormat
> for it.
>
> Willem
>
> Christian Schneider wrote:
>>
>> Hi Willem and Claus,
>>
>> I have looked into the JaxbDataformat to see what I should implement. As
>> what I need to do for the new DataFormat is quite similiar to the
>> JaxbDataFormat I think two aproaches may help to avoid duplicate code.
>>
>> 1) I could create a processor that only removes or adds the SOAP envelope
>> and body. So the route would look like:
>> JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
>> from("jms:myQueue").processor(new
>> SoapUnwrapper()).unmarshal(jaxbDataFormat).to("bean:myBean")
>>
>> Alternatively we could also use a SoapDataFormat instead of the processor.
>> Though I don´t know if adding or stripping SOAP is what you would like to
>> call a DataFormat.
>>
>> 2) I could add an option to JaxbDataFormat like soapSupport that switches
>> on or off the wrapping and unwrapping:
>> JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
>> jaxbDataFormat.setSoapSupport(true);
>> from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean")
>>
>> I think solution 1) better separates the Soap processing and makes it
>> easier to add functionality like SoapAction processing. On the other hand it
>> is more verbose and I am not sure if it performs fast enough.
>> Any opinions here?
>>
>> Btw. I think both aproaches will also work nicely with request reply
>> services. For solution 2) the server side could look like this:
>>
>> from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean").marshal(jaxbDataFormat)
>> I even guess that the client side is also quite easy using the
>> CamelProxyFactoryBean. Something like this oculd work (though I have not
>> tested it):
>>
>> from("direct:clientProxy").marshal(jaxbDataFormat).to("jms:myQueue").unmarshal(jaxbDataFormat)
>>
>> Greetings
>>
>> Christian
>>
>>
>> Am 20.01.2010 21:15, schrieb Claus Ibsen:
>>>
>>> On Wed, Jan 20, 2010 at 4:09 PM, Schneider Christian
>>> <Ch...@enbw.com>  wrote:
>>>
>>>>
>>>> Hi Willem and Claus,
>>>>
>>>> if you are interested I can prepare a SoapJaxbDataFormat. I propose to
>>>> add
>>>> it to the camel-jaxb component.
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Easy One way soap services

Posted by Willem Jiang <wi...@gmail.com>.
Hi Christian,

I think it dependents what you want to do for further enhancement of the 
your current solution. If you just want to add or strip the SOAP , an 
option of the JAXB DataFormat could be enough.
If you want to do more enhancement, you'd better create a SOAP 
DataFormat for it.

Willem

Christian Schneider wrote:
> Hi Willem and Claus,
> 
> I have looked into the JaxbDataformat to see what I should implement. As 
> what I need to do for the new DataFormat is quite similiar to the 
> JaxbDataFormat I think two aproaches may help to avoid duplicate code.
> 
> 1) I could create a processor that only removes or adds the SOAP 
> envelope and body. So the route would look like:
> JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
> from("jms:myQueue").processor(new 
> SoapUnwrapper()).unmarshal(jaxbDataFormat).to("bean:myBean")
> 
> Alternatively we could also use a SoapDataFormat instead of the 
> processor. Though I don´t know if adding or stripping SOAP is what you 
> would like to call a DataFormat.
> 
> 2) I could add an option to JaxbDataFormat like soapSupport that 
> switches on or off the wrapping and unwrapping:
> JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
> jaxbDataFormat.setSoapSupport(true);
> from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean")
> 
> I think solution 1) better separates the Soap processing and makes it 
> easier to add functionality like SoapAction processing. On the other 
> hand it is more verbose and I am not sure if it performs fast enough.
> Any opinions here?
> 
> Btw. I think both aproaches will also work nicely with request reply 
> services. For solution 2) the server side could look like this:
> from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean").marshal(jaxbDataFormat) 
> 
> I even guess that the client side is also quite easy using the 
> CamelProxyFactoryBean. Something like this oculd work (though I have not 
> tested it):
> from("direct:clientProxy").marshal(jaxbDataFormat).to("jms:myQueue").unmarshal(jaxbDataFormat) 
> 
> 
> Greetings
> 
> Christian
> 
> 
> Am 20.01.2010 21:15, schrieb Claus Ibsen:
>> On Wed, Jan 20, 2010 at 4:09 PM, Schneider Christian
>> <Ch...@enbw.com>  wrote:
>>   
>>> Hi Willem and Claus,
>>>
>>> if you are interested I can prepare a SoapJaxbDataFormat. I propose 
>>> to add
>>> it to the camel-jaxb component.
>>>
>>>
>>>      
>>
>>
>>    
> 
> 


Re: Easy One way soap services

Posted by Christian Schneider <ch...@die-schneider.net>.
Hi Willem and Claus,

I have looked into the JaxbDataformat to see what I should implement. As 
what I need to do for the new DataFormat is quite similiar to the 
JaxbDataFormat I think two aproaches may help to avoid duplicate code.

1) I could create a processor that only removes or adds the SOAP 
envelope and body. So the route would look like:
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
from("jms:myQueue").processor(new 
SoapUnwrapper()).unmarshal(jaxbDataFormat).to("bean:myBean")

Alternatively we could also use a SoapDataFormat instead of the 
processor. Though I don´t know if adding or stripping SOAP is what you 
would like to call a DataFormat.

2) I could add an option to JaxbDataFormat like soapSupport that 
switches on or off the wrapping and unwrapping:
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat();
jaxbDataFormat.setSoapSupport(true);
from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean")

I think solution 1) better separates the Soap processing and makes it 
easier to add functionality like SoapAction processing. On the other 
hand it is more verbose and I am not sure if it performs fast enough.
Any opinions here?

Btw. I think both aproaches will also work nicely with request reply 
services. For solution 2) the server side could look like this:
from("jms:myQueue").unmarshal(jaxbDataFormat).to("bean:myBean").marshal(jaxbDataFormat)
I even guess that the client side is also quite easy using the 
CamelProxyFactoryBean. Something like this oculd work (though I have not 
tested it):
from("direct:clientProxy").marshal(jaxbDataFormat).to("jms:myQueue").unmarshal(jaxbDataFormat)

Greetings

Christian


Am 20.01.2010 21:15, schrieb Claus Ibsen:
> On Wed, Jan 20, 2010 at 4:09 PM, Schneider Christian
> <Ch...@enbw.com>  wrote:
>    
>> Hi Willem and Claus,
>>
>> if you are interested I can prepare a SoapJaxbDataFormat. I propose to add
>> it to the camel-jaxb component.
>>
>>
>>      
>
>
>    


Re: Easy One way soap services

Posted by Claus Ibsen <cl...@gmail.com>.
On Wed, Jan 20, 2010 at 4:09 PM, Schneider Christian
<Ch...@enbw.com> wrote:
> Hi Willem and Claus,
>
> if you are interested I can prepare a SoapJaxbDataFormat. I propose to add
> it to the camel-jaxb component.
>

+1

> I think the goal must be to stay with really easy stuff. For everything more
> complex CXF is the much better solution. On the other hand I also try to
> understand what the core of the problem is. Perhaps we can also simplify CXF
> for some smaller cases so it is easier to setup and uses less dependencies.
>

Yeah good idea. Nice to start simple and then people can migrate to
CXF if they need more.



> Greetings
>
> Christian
>
>
>
> Christian Schneider
> Team Handel und Risikomanagement
> Informationsverarbeitung Business Solutions Trading
> EnBW Systeme Infrastruktur Support GmbH
>
> Informationsverarbeitung
> Business Solutions
> Handel und Dispatching
> Durlacher Allee 93
> 76131 Karlsruhe
>
> Tel : +49-(0)721-63-15482
> Mail: christian.schneider@enbw.com
>
> Sitz der Gesellschaft: Karlsruhe
> Handelsregister: Amtsgericht Mannheim   HRB 108550
> Vorsitzender des Aufsichtsrats: Dr. Bernhard Beck
> Geschäftsführer: Jochen Adenau, Dr. Peter Krampf
>
> -----Ursprüngliche Nachricht-----
> Von: Willem Jiang [mailto:willem.jiang@gmail.com]
> Gesendet: Mittwoch, 20. Januar 2010 15:47
> An: users@camel.apache.org
> Betreff: Re: Easy One way soap services
>
> Maybe we can add a SOAP data formate to deal with the soap envelop out
> of box.
>
> BTW, It could be easy to just take off or put on the soap envelop.
> But if there any WS* work involved, you had to switch to more flexible
> way ( to use camel-cxf component).
>
> Willem
> Claus Ibsen wrote:
>> On Wed, Jan 20, 2010 at 3:03 AM, Willem Jiang <wi...@gmail.com>
> wrote:
>>> Hi Christian,
>>>
>>> Your processor implements a easy way to unmarshal the soap message.
>>> But I think you can leverage JAXB DataFormat to do the same thing, all
> you
>>> need to do is using a camel-xslt component for soap envelop
> transformation.
>>>
>>
>> I think if its possible to make it easier then that is good. Using
>> JAXB + XSLT may do the trick but it would be much easier with a data
>> format, a type converter or a processor etc.
>>
>>
>>
>>> Willem
>>>
>>>
>>> Christian Schneider wrote:
>>>> Hi all,
>>>>
>>>> I am thinking about how to make one way services easier. Currently I
>>>> generate code for the service using cxf codegen and use the camel-cxf
> module
>>>> to create a client or endpoint that can be routed over jms using the
>>>> camel-jms component. Using CXF for this task is a little overkill as
> very
>>>> few features of CXF are used and quite a lot of configuration has to be
>>>> done. I wonder if this can be done easier.
>>>>
>>>> I have experimented with a possible solution for the server part. It
> looks
>>>> like this:
>>>> from("jms:myqueue").process(new
>>>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>>>
>>>> The idea is that a soap message for the service comes in over jms. The
>>>> soap processor parses the soap xml, strips the Envelope and Body and
>>>> unmarshals the content using JAXB. The processor needs the package name
> of
>>>> the generated stub code for the service. The advantage over using
> camel-cxf
>>>> is that there is much less configuration and you do not need cxf at
> runtime
>>>> (which means much less jars). Additionally the serviceHandler bean only
>>>> needs to have a method with the expected classs type as input parameter
> it
>>>> does not need to implement a service interface. I have added the code of
>>>> SoapProcessor to the mail as it is quite small.
>>>>
>>>> So what do you think? Does it make sense to have such small scale SOAP
>>>> functionality in camel?
>>>> I am thinking about turning my Processor into a DataFormat and provide
>>>> marshalling and unmarshalling. Does this make sense or is a processor
>>>> better?
>>>>
>>>> Greetings
>>>>
>>>> Christian
>>>>
>>>
>>
>>
>>
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

AW: Easy One way soap services

Posted by Schneider Christian <Ch...@enbw.com>.
Hi Willem and Claus,

if you are interested I can prepare a SoapJaxbDataFormat. I propose to add
it to the camel-jaxb component.

I think the goal must be to stay with really easy stuff. For everything more
complex CXF is the much better solution. On the other hand I also try to
understand what the core of the problem is. Perhaps we can also simplify CXF
for some smaller cases so it is easier to setup and uses less dependencies.

Greetings

Christian



Christian Schneider
Team Handel und Risikomanagement
Informationsverarbeitung Business Solutions Trading
EnBW Systeme Infrastruktur Support GmbH

Informationsverarbeitung 
Business Solutions
Handel und Dispatching
Durlacher Allee 93
76131 Karlsruhe

Tel : +49-(0)721-63-15482
Mail: christian.schneider@enbw.com

Sitz der Gesellschaft: Karlsruhe
Handelsregister: Amtsgericht Mannheim   HRB 108550
Vorsitzender des Aufsichtsrats: Dr. Bernhard Beck
Geschäftsführer: Jochen Adenau, Dr. Peter Krampf

-----Ursprüngliche Nachricht-----
Von: Willem Jiang [mailto:willem.jiang@gmail.com] 
Gesendet: Mittwoch, 20. Januar 2010 15:47
An: users@camel.apache.org
Betreff: Re: Easy One way soap services

Maybe we can add a SOAP data formate to deal with the soap envelop out 
of box.

BTW, It could be easy to just take off or put on the soap envelop.
But if there any WS* work involved, you had to switch to more flexible 
way ( to use camel-cxf component).

Willem
Claus Ibsen wrote:
> On Wed, Jan 20, 2010 at 3:03 AM, Willem Jiang <wi...@gmail.com>
wrote:
>> Hi Christian,
>>
>> Your processor implements a easy way to unmarshal the soap message.
>> But I think you can leverage JAXB DataFormat to do the same thing, all
you
>> need to do is using a camel-xslt component for soap envelop
transformation.
>>
> 
> I think if its possible to make it easier then that is good. Using
> JAXB + XSLT may do the trick but it would be much easier with a data
> format, a type converter or a processor etc.
> 
> 
> 
>> Willem
>>
>>
>> Christian Schneider wrote:
>>> Hi all,
>>>
>>> I am thinking about how to make one way services easier. Currently I
>>> generate code for the service using cxf codegen and use the camel-cxf
module
>>> to create a client or endpoint that can be routed over jms using the
>>> camel-jms component. Using CXF for this task is a little overkill as
very
>>> few features of CXF are used and quite a lot of configuration has to be
>>> done. I wonder if this can be done easier.
>>>
>>> I have experimented with a possible solution for the server part. It
looks
>>> like this:
>>> from("jms:myqueue").process(new
>>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>>
>>> The idea is that a soap message for the service comes in over jms. The
>>> soap processor parses the soap xml, strips the Envelope and Body and
>>> unmarshals the content using JAXB. The processor needs the package name
of
>>> the generated stub code for the service. The advantage over using
camel-cxf
>>> is that there is much less configuration and you do not need cxf at
runtime
>>> (which means much less jars). Additionally the serviceHandler bean only
>>> needs to have a method with the expected classs type as input parameter
it
>>> does not need to implement a service interface. I have added the code of
>>> SoapProcessor to the mail as it is quite small.
>>>
>>> So what do you think? Does it make sense to have such small scale SOAP
>>> functionality in camel?
>>> I am thinking about turning my Processor into a DataFormat and provide
>>> marshalling and unmarshalling. Does this make sense or is a processor
>>> better?
>>>
>>> Greetings
>>>
>>> Christian
>>>
>>
> 
> 
> 


Re: Easy One way soap services

Posted by Willem Jiang <wi...@gmail.com>.
Maybe we can add a SOAP data formate to deal with the soap envelop out 
of box.

BTW, It could be easy to just take off or put on the soap envelop.
But if there any WS* work involved, you had to switch to more flexible 
way ( to use camel-cxf component).

Willem
Claus Ibsen wrote:
> On Wed, Jan 20, 2010 at 3:03 AM, Willem Jiang <wi...@gmail.com> wrote:
>> Hi Christian,
>>
>> Your processor implements a easy way to unmarshal the soap message.
>> But I think you can leverage JAXB DataFormat to do the same thing, all you
>> need to do is using a camel-xslt component for soap envelop transformation.
>>
> 
> I think if its possible to make it easier then that is good. Using
> JAXB + XSLT may do the trick but it would be much easier with a data
> format, a type converter or a processor etc.
> 
> 
> 
>> Willem
>>
>>
>> Christian Schneider wrote:
>>> Hi all,
>>>
>>> I am thinking about how to make one way services easier. Currently I
>>> generate code for the service using cxf codegen and use the camel-cxf module
>>> to create a client or endpoint that can be routed over jms using the
>>> camel-jms component. Using CXF for this task is a little overkill as very
>>> few features of CXF are used and quite a lot of configuration has to be
>>> done. I wonder if this can be done easier.
>>>
>>> I have experimented with a possible solution for the server part. It looks
>>> like this:
>>> from("jms:myqueue").process(new
>>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>>
>>> The idea is that a soap message for the service comes in over jms. The
>>> soap processor parses the soap xml, strips the Envelope and Body and
>>> unmarshals the content using JAXB. The processor needs the package name of
>>> the generated stub code for the service. The advantage over using camel-cxf
>>> is that there is much less configuration and you do not need cxf at runtime
>>> (which means much less jars). Additionally the serviceHandler bean only
>>> needs to have a method with the expected classs type as input parameter it
>>> does not need to implement a service interface. I have added the code of
>>> SoapProcessor to the mail as it is quite small.
>>>
>>> So what do you think? Does it make sense to have such small scale SOAP
>>> functionality in camel?
>>> I am thinking about turning my Processor into a DataFormat and provide
>>> marshalling and unmarshalling. Does this make sense or is a processor
>>> better?
>>>
>>> Greetings
>>>
>>> Christian
>>>
>>
> 
> 
> 


Re: Easy One way soap services

Posted by Claus Ibsen <cl...@gmail.com>.
On Wed, Jan 20, 2010 at 3:03 AM, Willem Jiang <wi...@gmail.com> wrote:
> Hi Christian,
>
> Your processor implements a easy way to unmarshal the soap message.
> But I think you can leverage JAXB DataFormat to do the same thing, all you
> need to do is using a camel-xslt component for soap envelop transformation.
>

I think if its possible to make it easier then that is good. Using
JAXB + XSLT may do the trick but it would be much easier with a data
format, a type converter or a processor etc.



> Willem
>
>
> Christian Schneider wrote:
>>
>> Hi all,
>>
>> I am thinking about how to make one way services easier. Currently I
>> generate code for the service using cxf codegen and use the camel-cxf module
>> to create a client or endpoint that can be routed over jms using the
>> camel-jms component. Using CXF for this task is a little overkill as very
>> few features of CXF are used and quite a lot of configuration has to be
>> done. I wonder if this can be done easier.
>>
>> I have experimented with a possible solution for the server part. It looks
>> like this:
>> from("jms:myqueue").process(new
>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>
>> The idea is that a soap message for the service comes in over jms. The
>> soap processor parses the soap xml, strips the Envelope and Body and
>> unmarshals the content using JAXB. The processor needs the package name of
>> the generated stub code for the service. The advantage over using camel-cxf
>> is that there is much less configuration and you do not need cxf at runtime
>> (which means much less jars). Additionally the serviceHandler bean only
>> needs to have a method with the expected classs type as input parameter it
>> does not need to implement a service interface. I have added the code of
>> SoapProcessor to the mail as it is quite small.
>>
>> So what do you think? Does it make sense to have such small scale SOAP
>> functionality in camel?
>> I am thinking about turning my Processor into a DataFormat and provide
>> marshalling and unmarshalling. Does this make sense or is a processor
>> better?
>>
>> Greetings
>>
>> Christian
>>
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Easy One way soap services

Posted by Willem Jiang <wi...@gmail.com>.
Hi Christian,

Your processor implements a easy way to unmarshal the soap message.
But I think you can leverage JAXB DataFormat to do the same thing, all 
you need to do is using a camel-xslt component for soap envelop 
transformation.

Willem


Christian Schneider wrote:
> Hi all,
> 
> I am thinking about how to make one way services easier. Currently I 
> generate code for the service using cxf codegen and use the camel-cxf 
> module to create a client or endpoint that can be routed over jms using 
> the camel-jms component. Using CXF for this task is a little overkill as 
> very few features of CXF are used and quite a lot of configuration has 
> to be done. I wonder if this can be done easier.
> 
> I have experimented with a possible solution for the server part. It 
> looks like this:
> from("jms:myqueue").process(new 
> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
> 
> The idea is that a soap message for the service comes in over jms. The 
> soap processor parses the soap xml, strips the Envelope and Body and 
> unmarshals the content using JAXB. The processor needs the package name 
> of the generated stub code for the service. The advantage over using 
> camel-cxf is that there is much less configuration and you do not need 
> cxf at runtime (which means much less jars). Additionally the 
> serviceHandler bean only needs to have a method with the expected classs 
> type as input parameter it does not need to implement a service 
> interface. I have added the code of SoapProcessor to the mail as it is 
> quite small.
> 
> So what do you think? Does it make sense to have such small scale SOAP 
> functionality in camel?
> I am thinking about turning my Processor into a DataFormat and provide 
> marshalling and unmarshalling. Does this make sense or is a processor 
> better?
> 
> Greetings
> 
> Christian
> 


Re: Easy One way soap services

Posted by William Tam <em...@gmail.com>.
As another option, you can use the cxfbean compound but your bean
needs to have JAXWS annotations.


		<route>
			<from uri="jetty:http://localhost:9090?matchOnUriPrefix=true" />
			<to uri="cxfbean:jaxwsBean" />
		</route>		


Please see the unit test here:
https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/cxfbean/CxfBeanTest.java
(see testJaxWsBean)
https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/cxfbean/CxfBeanTest-context.xml


The only catch is you will probably the first person to do
"from(jms).to(cxfbean)".


On Tue, Jan 19, 2010 at 4:53 PM, Christian Schneider
<ch...@die-schneider.net> wrote:
> Hi all,
>
> I am thinking about how to make one way services easier. Currently I
> generate code for the service using cxf codegen and use the camel-cxf module
> to create a client or endpoint that can be routed over jms using the
> camel-jms component. Using CXF for this task is a little overkill as very
> few features of CXF are used and quite a lot of configuration has to be
> done. I wonder if this can be done easier.
>
> I have experimented with a possible solution for the server part. It looks
> like this:
> from("jms:myqueue").process(new
> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>
> The idea is that a soap message for the service comes in over jms. The soap
> processor parses the soap xml, strips the Envelope and Body and unmarshals
> the content using JAXB. The processor needs the package name of the
> generated stub code for the service. The advantage over using camel-cxf is
> that there is much less configuration and you do not need cxf at runtime
> (which means much less jars). Additionally the serviceHandler bean only
> needs to have a method with the expected classs type as input parameter it
> does not need to implement a service interface. I have added the code of
> SoapProcessor to the mail as it is quite small.
>
> So what do you think? Does it make sense to have such small scale SOAP
> functionality in camel?
> I am thinking about turning my Processor into a DataFormat and provide
> marshalling and unmarshalling. Does this make sense or is a processor
> better?
>
> Greetings
>
> Christian
>
> --
>
> Christian Schneider
> ---
> http://www.liquid-reality.de
>
> ----
>
>
> import java.io.InputStream;
> import java.util.Iterator;
>
> import javax.xml.bind.JAXBContext;
> import javax.xml.bind.JAXBElement;
> import javax.xml.bind.JAXBException;
> import javax.xml.bind.Unmarshaller;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.xpath.XPath;
> import javax.xml.xpath.XPathConstants;
> import javax.xml.xpath.XPathExpression;
> import javax.xml.xpath.XPathExpressionException;
> import javax.xml.xpath.XPathFactory;
>
> import org.apache.camel.Exchange;
> import org.apache.camel.Processor;
> import org.w3c.dom.Element;
> import org.xml.sax.InputSource;
>
> public class SoapProcessor implements Processor {
>
>        private XPathExpression xpathExpression;
>        private Unmarshaller unmarshaller;
>
>        public SoapProcessor(String jaxbPackage) {
>                super();
>                XPath xpath = XPathFactory.newInstance().newXPath();
>                xpath.setNamespaceContext(new SoapNameSpaceContext());
>                try {
>                        xpathExpression =
> xpath.compile("/soap:Envelope/soap:Body/*");
>                        JAXBContext jContext =
> JAXBContext.newInstance(jaxbPackage);
>                        unmarshaller = jContext.createUnmarshaller();
>                } catch (XPathExpressionException e) {
>                        throw new RuntimeException(e.getMessage(), e);
>                } catch (JAXBException e) {
>                        throw new RuntimeException(e.getMessage(), e);
>                }
>
>        }
>
>        private final class SoapNameSpaceContext implements NamespaceContext
> {
>                private static final String SOAP_NAMESPACE =
> "http://schemas.xmlsoap.org/soap/envelope/";
>
>                public Iterator<?>  getPrefixes(String namespaceURI) {
>                        return null;
>                }
>
>                public String getPrefix(String namespaceURI) {
>                        return null;
>                }
>
>                public String getNamespaceURI(String prefix) {
>                        return SOAP_NAMESPACE;
>                }
>        }
>
>        public void process(Exchange exchange) throws Exception {
>                InputStream request =
> exchange.getIn().getBody(InputStream.class);
>                InputSource is = new InputSource(request);
>                Element payload = (Element) xpathExpression.evaluate(is,
> XPathConstants.NODE);
>                JAXBElement<?>  el = (JAXBElement<?>)
> unmarshaller.unmarshal(payload);
>                Object o = el.getValue();
>                exchange.getIn().setBody(o);
>        }
>
> }
>
>

Re: Easy One way soap services

Posted by William Tam <em...@gmail.com>.
I could be wrong but I think when camel-cxf PAYLOAD mode was developed, 
the CXF Dispatch/Provider interface support wasn't quite ready (or we 
haven't done enough due diligence).   I agreed with you the benefit.  We 
could rewriting it using the Dispatch/Provider APIs.  However, I 
seriously doubt that we could integrate with CXF without directly 
invoking the non-APIs classes.  I mean that would be nice.  There is a 
soap component in camel-cxf which is pretty much not being used and that 
makes it look more complex then it really is.  A good chunk of the 
"complexity" are doing with header filtering, converting/binding Camel 
to CXF message, standard Camel Producer/Consumer/Endpoint/Spring which 
you need either way.  The CXF interceptor stuff which I agree we should 
avoid actually only accounts for small portion of the code (10 classes 
in org.apache.camel.component.cxf.intercepters and 2 of the 10 XML* are 
not used and two of them are Abstract classes).

Daniel Kulp wrote:
> Quite honestly, I'm not sure why the CXF stuff in Camel has to be so
> complex.   To me, it should be based more on the technology in CXF that
> supports the JAX-WS Dispatch/Provider stuff (or implemented via the JAX-WS
> Dispatch/Provider stuff).   In this case, if it was a "PAYLOAD" mode
> Provider, it ends up as essentially the same thing.  You get the payload as
> a "Source" (in some cases, a StaxSource so streaming can be maintained) and
> all the "soap" stuff is not there.  If camel needs the whole message, the
> Provider is put in MESSAGE mode.   
>
> The benefit of the Provider/Dispatch stuff is that you DO get all the
> complext WS-* processing and things like schema validation and other
> important things that CXF provides, but you don't have to do all the code
> generation and things like that.    
>
>
> Dan
>
>
>
>
> Christian Schneider wrote:
>   
>> Hi all,
>>
>> I am thinking about how to make one way services easier. Currently I 
>> generate code for the service using cxf codegen and use the camel-cxf 
>> module to create a client or endpoint that can be routed over jms using 
>> the camel-jms component. Using CXF for this task is a little overkill as 
>> very few features of CXF are used and quite a lot of configuration has 
>> to be done. I wonder if this can be done easier.
>>
>> I have experimented with a possible solution for the server part. It 
>> looks like this:
>> from("jms:myqueue").process(new 
>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>
>> The idea is that a soap message for the service comes in over jms. The 
>> soap processor parses the soap xml, strips the Envelope and Body and 
>> unmarshals the content using JAXB. The processor needs the package name 
>> of the generated stub code for the service. The advantage over using 
>> camel-cxf is that there is much less configuration and you do not need 
>> cxf at runtime (which means much less jars). Additionally the 
>> serviceHandler bean only needs to have a method with the expected classs 
>> type as input parameter it does not need to implement a service 
>> interface. I have added the code of SoapProcessor to the mail as it is 
>> quite small.
>>
>> So what do you think? Does it make sense to have such small scale SOAP 
>> functionality in camel?
>> I am thinking about turning my Processor into a DataFormat and provide 
>> marshalling and unmarshalling. Does this make sense or is a processor 
>> better?
>>
>> Greetings
>>
>> Christian
>>
>> -- 
>>
>> Christian Schneider
>> ---
>> http://www.liquid-reality.de
>>
>> ----
>>
>>
>> import java.io.InputStream;
>> import java.util.Iterator;
>>
>> import javax.xml.bind.JAXBContext;
>> import javax.xml.bind.JAXBElement;
>> import javax.xml.bind.JAXBException;
>> import javax.xml.bind.Unmarshaller;
>> import javax.xml.namespace.NamespaceContext;
>> import javax.xml.xpath.XPath;
>> import javax.xml.xpath.XPathConstants;
>> import javax.xml.xpath.XPathExpression;
>> import javax.xml.xpath.XPathExpressionException;
>> import javax.xml.xpath.XPathFactory;
>>
>> import org.apache.camel.Exchange;
>> import org.apache.camel.Processor;
>> import org.w3c.dom.Element;
>> import org.xml.sax.InputSource;
>>
>> public class SoapProcessor implements Processor {
>>
>> 	private XPathExpression xpathExpression;
>> 	private Unmarshaller unmarshaller;
>>
>> 	public SoapProcessor(String jaxbPackage) {
>> 		super();
>> 		XPath xpath = XPathFactory.newInstance().newXPath();
>> 		xpath.setNamespaceContext(new SoapNameSpaceContext());
>> 		try {
>> 			xpathExpression = xpath.compile("/soap:Envelope/soap:Body/*");
>> 			JAXBContext jContext = JAXBContext.newInstance(jaxbPackage);
>> 			unmarshaller = jContext.createUnmarshaller();
>> 		} catch (XPathExpressionException e) {
>> 			throw new RuntimeException(e.getMessage(), e);
>> 		} catch (JAXBException e) {
>> 			throw new RuntimeException(e.getMessage(), e);
>> 		}
>> 		
>> 	}
>>
>> 	private final class SoapNameSpaceContext implements NamespaceContext {
>> 		private static final String SOAP_NAMESPACE =
>> "http://schemas.xmlsoap.org/soap/envelope/";
>>
>> 		public Iterator<?>  getPrefixes(String namespaceURI) {
>> 			return null;
>> 		}
>>
>> 		public String getPrefix(String namespaceURI) {
>> 			return null;
>> 		}
>>
>> 		public String getNamespaceURI(String prefix) {
>> 			return SOAP_NAMESPACE;
>> 		}
>> 	}
>>
>> 	public void process(Exchange exchange) throws Exception {
>> 		InputStream request = exchange.getIn().getBody(InputStream.class);
>> 		InputSource is = new InputSource(request);
>> 		Element payload = (Element) xpathExpression.evaluate(is,
>> XPathConstants.NODE);
>> 		JAXBElement<?>  el = (JAXBElement<?>) unmarshaller.unmarshal(payload);
>> 		Object o = el.getValue();
>> 		exchange.getIn().setBody(o);
>> 	}
>>
>> }
>>
>>
>>
>>     
>
>   

Re: Easy One way soap services

Posted by Willem Jiang <wi...@gmail.com>.
Hi Dan,

What we do in camel-cxf is try to reuse everything what CXF can provide.
First we use the cxf-simple-front and cxf-jaxws-front endpoint to export 
or consumer the WS services, then we provides MESSAGE, and PAYLOAD 
DataFormat by massage the interceptors ourself, then we have cxfBeans, 
cxfrs components.

We could avoid to tough CXF internal API by leveraging the JAX-WS 
Dispatch/Provider API, but we still need to support other features of CXF.

Willem

Daniel Kulp wrote:
> 
> Quite honestly, I'm not sure why the CXF stuff in Camel has to be so
> complex.   To me, it should be based more on the technology in CXF that
> supports the JAX-WS Dispatch/Provider stuff (or implemented via the JAX-WS
> Dispatch/Provider stuff).   In this case, if it was a "PAYLOAD" mode
> Provider, it ends up as essentially the same thing.  You get the payload as
> a "Source" (in some cases, a StaxSource so streaming can be maintained) and
> all the "soap" stuff is not there.  If camel needs the whole message, the
> Provider is put in MESSAGE mode.   
> 
> The benefit of the Provider/Dispatch stuff is that you DO get all the
> complext WS-* processing and things like schema validation and other
> important things that CXF provides, but you don't have to do all the code
> generation and things like that.    
> 
> 
> Dan
> 
> 
> 
> 
> Christian Schneider wrote:
>> Hi all,
>>
>> I am thinking about how to make one way services easier. Currently I 
>> generate code for the service using cxf codegen and use the camel-cxf 
>> module to create a client or endpoint that can be routed over jms using 
>> the camel-jms component. Using CXF for this task is a little overkill as 
>> very few features of CXF are used and quite a lot of configuration has 
>> to be done. I wonder if this can be done easier.
>>
>> I have experimented with a possible solution for the server part. It 
>> looks like this:
>> from("jms:myqueue").process(new 
>> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
>>
>> The idea is that a soap message for the service comes in over jms. The 
>> soap processor parses the soap xml, strips the Envelope and Body and 
>> unmarshals the content using JAXB. The processor needs the package name 
>> of the generated stub code for the service. The advantage over using 
>> camel-cxf is that there is much less configuration and you do not need 
>> cxf at runtime (which means much less jars). Additionally the 
>> serviceHandler bean only needs to have a method with the expected classs 
>> type as input parameter it does not need to implement a service 
>> interface. I have added the code of SoapProcessor to the mail as it is 
>> quite small.
>>
>> So what do you think? Does it make sense to have such small scale SOAP 
>> functionality in camel?
>> I am thinking about turning my Processor into a DataFormat and provide 
>> marshalling and unmarshalling. Does this make sense or is a processor 
>> better?
>>
>> Greetings
>>
>> Christian
>>
>> -- 
>>
>> Christian Schneider
>> ---
>> http://www.liquid-reality.de
>>
>> ----
>>
>>
>> import java.io.InputStream;
>> import java.util.Iterator;
>>
>> import javax.xml.bind.JAXBContext;
>> import javax.xml.bind.JAXBElement;
>> import javax.xml.bind.JAXBException;
>> import javax.xml.bind.Unmarshaller;
>> import javax.xml.namespace.NamespaceContext;
>> import javax.xml.xpath.XPath;
>> import javax.xml.xpath.XPathConstants;
>> import javax.xml.xpath.XPathExpression;
>> import javax.xml.xpath.XPathExpressionException;
>> import javax.xml.xpath.XPathFactory;
>>
>> import org.apache.camel.Exchange;
>> import org.apache.camel.Processor;
>> import org.w3c.dom.Element;
>> import org.xml.sax.InputSource;
>>
>> public class SoapProcessor implements Processor {
>>
>> 	private XPathExpression xpathExpression;
>> 	private Unmarshaller unmarshaller;
>>
>> 	public SoapProcessor(String jaxbPackage) {
>> 		super();
>> 		XPath xpath = XPathFactory.newInstance().newXPath();
>> 		xpath.setNamespaceContext(new SoapNameSpaceContext());
>> 		try {
>> 			xpathExpression = xpath.compile("/soap:Envelope/soap:Body/*");
>> 			JAXBContext jContext = JAXBContext.newInstance(jaxbPackage);
>> 			unmarshaller = jContext.createUnmarshaller();
>> 		} catch (XPathExpressionException e) {
>> 			throw new RuntimeException(e.getMessage(), e);
>> 		} catch (JAXBException e) {
>> 			throw new RuntimeException(e.getMessage(), e);
>> 		}
>> 		
>> 	}
>>
>> 	private final class SoapNameSpaceContext implements NamespaceContext {
>> 		private static final String SOAP_NAMESPACE =
>> "http://schemas.xmlsoap.org/soap/envelope/";
>>
>> 		public Iterator<?>  getPrefixes(String namespaceURI) {
>> 			return null;
>> 		}
>>
>> 		public String getPrefix(String namespaceURI) {
>> 			return null;
>> 		}
>>
>> 		public String getNamespaceURI(String prefix) {
>> 			return SOAP_NAMESPACE;
>> 		}
>> 	}
>>
>> 	public void process(Exchange exchange) throws Exception {
>> 		InputStream request = exchange.getIn().getBody(InputStream.class);
>> 		InputSource is = new InputSource(request);
>> 		Element payload = (Element) xpathExpression.evaluate(is,
>> XPathConstants.NODE);
>> 		JAXBElement<?>  el = (JAXBElement<?>) unmarshaller.unmarshal(payload);
>> 		Object o = el.getValue();
>> 		exchange.getIn().setBody(o);
>> 	}
>>
>> }
>>
>>
>>
> 


Re: Easy One way soap services

Posted by Daniel Kulp <dk...@apache.org>.

Quite honestly, I'm not sure why the CXF stuff in Camel has to be so
complex.   To me, it should be based more on the technology in CXF that
supports the JAX-WS Dispatch/Provider stuff (or implemented via the JAX-WS
Dispatch/Provider stuff).   In this case, if it was a "PAYLOAD" mode
Provider, it ends up as essentially the same thing.  You get the payload as
a "Source" (in some cases, a StaxSource so streaming can be maintained) and
all the "soap" stuff is not there.  If camel needs the whole message, the
Provider is put in MESSAGE mode.   

The benefit of the Provider/Dispatch stuff is that you DO get all the
complext WS-* processing and things like schema validation and other
important things that CXF provides, but you don't have to do all the code
generation and things like that.    


Dan




Christian Schneider wrote:
> 
> Hi all,
> 
> I am thinking about how to make one way services easier. Currently I 
> generate code for the service using cxf codegen and use the camel-cxf 
> module to create a client or endpoint that can be routed over jms using 
> the camel-jms component. Using CXF for this task is a little overkill as 
> very few features of CXF are used and quite a lot of configuration has 
> to be done. I wonder if this can be done easier.
> 
> I have experimented with a possible solution for the server part. It 
> looks like this:
> from("jms:myqueue").process(new 
> SoapProcessor("com.example.customerservice")).to("bean:serviceHandler");
> 
> The idea is that a soap message for the service comes in over jms. The 
> soap processor parses the soap xml, strips the Envelope and Body and 
> unmarshals the content using JAXB. The processor needs the package name 
> of the generated stub code for the service. The advantage over using 
> camel-cxf is that there is much less configuration and you do not need 
> cxf at runtime (which means much less jars). Additionally the 
> serviceHandler bean only needs to have a method with the expected classs 
> type as input parameter it does not need to implement a service 
> interface. I have added the code of SoapProcessor to the mail as it is 
> quite small.
> 
> So what do you think? Does it make sense to have such small scale SOAP 
> functionality in camel?
> I am thinking about turning my Processor into a DataFormat and provide 
> marshalling and unmarshalling. Does this make sense or is a processor 
> better?
> 
> Greetings
> 
> Christian
> 
> -- 
> 
> Christian Schneider
> ---
> http://www.liquid-reality.de
> 
> ----
> 
> 
> import java.io.InputStream;
> import java.util.Iterator;
> 
> import javax.xml.bind.JAXBContext;
> import javax.xml.bind.JAXBElement;
> import javax.xml.bind.JAXBException;
> import javax.xml.bind.Unmarshaller;
> import javax.xml.namespace.NamespaceContext;
> import javax.xml.xpath.XPath;
> import javax.xml.xpath.XPathConstants;
> import javax.xml.xpath.XPathExpression;
> import javax.xml.xpath.XPathExpressionException;
> import javax.xml.xpath.XPathFactory;
> 
> import org.apache.camel.Exchange;
> import org.apache.camel.Processor;
> import org.w3c.dom.Element;
> import org.xml.sax.InputSource;
> 
> public class SoapProcessor implements Processor {
> 
> 	private XPathExpression xpathExpression;
> 	private Unmarshaller unmarshaller;
> 
> 	public SoapProcessor(String jaxbPackage) {
> 		super();
> 		XPath xpath = XPathFactory.newInstance().newXPath();
> 		xpath.setNamespaceContext(new SoapNameSpaceContext());
> 		try {
> 			xpathExpression = xpath.compile("/soap:Envelope/soap:Body/*");
> 			JAXBContext jContext = JAXBContext.newInstance(jaxbPackage);
> 			unmarshaller = jContext.createUnmarshaller();
> 		} catch (XPathExpressionException e) {
> 			throw new RuntimeException(e.getMessage(), e);
> 		} catch (JAXBException e) {
> 			throw new RuntimeException(e.getMessage(), e);
> 		}
> 		
> 	}
> 
> 	private final class SoapNameSpaceContext implements NamespaceContext {
> 		private static final String SOAP_NAMESPACE =
> "http://schemas.xmlsoap.org/soap/envelope/";
> 
> 		public Iterator<?>  getPrefixes(String namespaceURI) {
> 			return null;
> 		}
> 
> 		public String getPrefix(String namespaceURI) {
> 			return null;
> 		}
> 
> 		public String getNamespaceURI(String prefix) {
> 			return SOAP_NAMESPACE;
> 		}
> 	}
> 
> 	public void process(Exchange exchange) throws Exception {
> 		InputStream request = exchange.getIn().getBody(InputStream.class);
> 		InputSource is = new InputSource(request);
> 		Element payload = (Element) xpathExpression.evaluate(is,
> XPathConstants.NODE);
> 		JAXBElement<?>  el = (JAXBElement<?>) unmarshaller.unmarshal(payload);
> 		Object o = el.getValue();
> 		exchange.getIn().setBody(o);
> 	}
> 
> }
> 
> 
> 

-- 
View this message in context: http://old.nabble.com/Easy-One-way-soap-services-tp27233386p27261053.html
Sent from the Camel - Users mailing list archive at Nabble.com.