What is the BC-SOAP ?This binding component allows to interact with external Web Services and to expose JBI services as Web Services. A JBI MessageExchange sent to a ServiceEndpoint (mapped to a Web Service) is transformed into a SOAP message and sent to the linked external web service. A SOAP message received on an exposed web service is transformed into a JBI MessageExchange and sent to the corresponding JBI ServiceEndpoint. This component is based on the Petals CDK. If you want more details about SOAP, you can consult this W3C specification : http://www.w3.org/TR/soap/. FeaturesThe petals-bc-soap is based on the petals-cdk v4.x, Apache Axis2 v1.4.1 (http://ws.apache.org/axis2/) and Mortbay Jetty v6.1.4 (http://jetty.codehaus.org/jetty/). It provides the following features :
Component ConfigurationThe component can be configured through its JBI descriptor file like this : <?xml version="1.0" encoding="UTF-8"?> <jbi:jbi version="1.0" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5" xmlns:soap="http://petals.ow2.org/components/soap/version-3.2"> <jbi:component type="binding-component" bootstrap-class-loader-delegation="parent-first"> <jbi:identification> <jbi:name>petals-bc-soap</jbi:name> <jbi:description> The SOAP Binding Component (based on Axis2 + Jetty)</jbi:description> </jbi:identification> <jbi:component-class-name>org.ow2.petals.binding.soap.SoapComponent</jbi:component-class-name> <jbi:component-class-path>...</jbi:component-class-path> <jbi:bootstrap-class-name>org.ow2.petals.binding.soap.SoapBootstrap</jbi:bootstrap-class-name> <jbi:bootstrap-class-path>...</jbi:bootstrap-class-path> <!-- Component Development Kit Parameters --> <petalsCDK:acceptor-pool-size>5</petalsCDK:acceptor-pool-size> <petalsCDK:processor-pool-size>10</petalsCDK:processor-pool-size> <petalsCDK:ignored-status>DONE_AND_ERROR_IGNORED</petalsCDK:ignored-status> <petalsCDK:properties-file /> <petalsCDK:performance-notifications>false</petalsCDK:performance-notifications> <petalsCDK:jbi-listener-class-name> org.ow2.petals.binding.soap.listener.outgoing.JBIListener </petalsCDK:jbi-listener-class-name> <petalsCDK:external-listener-classname> org.ow2.petals.binding.soap.listener.incoming.SoapExternalListener </petalsCDK:externallistener-class-name> <!-- SOAP Component Parameters --> <soap:http-port>8084</soap:http-port> <soap:http-host>148.39.34.45</soap:http-host> <soap:http-services-list>true</soap:http-services-list> <soap:http-services-context>petals</soap:http-services-context> <soap:http-services-mapping>services</soap:http-services-mapping> <soap:http-thread-pool-size-min>2</soap:http-thread-pool-size-min> <soap:http-thread-pool-size-max>50</soap:http-thread-pool-size-max> <soap:http-acceptors>4</soap:http-acceptors> </jbi:component> </jbi:jbi>
Unable to render {include} Couldn't find a page to include called: 0 CDK Component Configuration Table
Definition of CDK parameter scope :
The SOAP component specific parameters can be also set through JMX during its installation phase. Service ConfigurationSend a JBI message to an external Web Servicetodo Service Unit descriptortodo Send a JBI message from an incoming SOAP messagetodo Service Unit descriptortodo REST ServicesIntroductionThe SOAP binding component provides REST (REpresentational State Transfer (http://en.wikipedia.org/wiki/Representational_State_Transfer)) services features since release 3.1. The REST feature is provided by Axis2 in the component. ConfigurationThe component can be configured to :
Provide mode : Provide access to external REST ServiceIn order to activate REST mode, the Service Unit (in provide mode) must be configured like this : <?xml version="1.0" encoding="UTF-8"?> <jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-4.0" xmlns:soap="http://petals.ow2.org/components/soap/version-3.1" xmlns:sample="http://petals.ow2.org/soap/sample"> <!-- Import a Service into PEtALS or Expose a PEtALS Service => use a BC. --> <jbi:services binding-component="true"> <!-- Import a Service into PEtALS => provides a Service. --> <jbi:provides interface-name="sample:SoapInterface" service-name="sample:SoapInterface" endpoint-name="SoapInterfaceEndpoint"> <!-- CDK specific fields --> <petalsCDK:mep xsi:nil="true"/> <!-- WSDL file --> <petalsCDK:wsdl> http://example.org/service/SampleWebService?wsdl </petalsCDK:wsdl> <!-- SOAP specific fields --> <soap:address> http://example.org/param1={xpathexpression1}&param2={xpathexpression1} </soap:address> <soap:mode>REST</soap:mode> <soap:rest-http-method>GET</soap:rest-http-method> </jbi:provides> </jbi:services> </jbi:jbi>
Consume mode : Expose JBI Service as as REST Service<jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-4.0" xmlns:helloworld="http://petals.ow2.org/helloworld" xmlns:soap="http://petals.ow2.org/components/soap/version-3.1"> <!-- Import a Service into PEtALS or Expose a PEtALS Service => use a BC. --> <jbi:services binding-component="true"> <!-- Import a Service into PEtALS => provides a Service. --> <jbi:consumes interface-name="helloworld:Helloworld" service-name="helloworld:HelloworldService" endpoint-name="HelloworldEndpoint"> <!-- CDK specific fields --> <petalsCDK:mep>InOut</petalsCDK:mep> <petalsCDK:operation>getXXX</petalsCDK:operation> <!-- SOAP specific fields --> <soap:address>RESTServiceName</soap:address> <soap:mode>REST</soap:mode> <soap:rest-add-namespace-uri>http://petals.ow2.org/soapbc</soap:rest-add-namespace-uri> <soap:rest-add-namespace-prefix>ns1</soap:rest-add-namespace-prefix> <soap:rest-remove-prefix-on-response>*</soap:rest-remove-prefix-on-response> </jbi:consumes> </jbi:services> </jbi:jbi>
The component will create a JBI message depending on the http-method used in the incoming request :
In all the cases the namespaces are added to the JBI message if they are specified in the Service Unit configuration. The JBI operation is created from the incoming REST query. The operation is extracted from the URL. A URL like http://<host>:<port>/petals/services/RESTService/operation?param1=value1¶m2=value2 will produce the 'operation' JBI operation. SamplesProvide modeIn this sample, we are going to provide the Yahoo Weather Service (http://developer.yahoo.com/weather/) as JBI Service inside the JBI environment. It is possible by configuring a Service Unit in provider mode : <?xml version="1.0" encoding="UTF-8"?> <jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-4.0" xmlns:soap="http://petals.ow2.org/components/soap/version-3.1" xmlns:sample="http://petals.ow2.org/soap/sample"> <!-- Import a Service into PEtALS or Expose a PEtALS Service => use a BC. --> <jbi:services binding-component="true"> <!-- Import a Service into PEtALS => provides a Service. --> <jbi:provides interface-name="sample:YahooWeatherInterface" service-name="sample:YahooWeatherService" endpoint-name="YahooWeatherEndpoint"> <!-- CDK specific fields --> <petalsCDK:mep xsi:nil="true"/> <!-- WSDL file --> <petalsCDK:wsdl>Weather.wsdl</petalsCDK:wsdl> <!-- SOAP specific fields --> <soap:address> http://weather.yahooapis.com/forecastrss?p={/*[local-name()='getWeather'][1]/*[ localname()='citycode'][1]}&u={/*[local-name()='getWeather'][1]/*[local-name()='unit'][1]} </soap:address> <!-- The previous address has been formatted for display purpose --> <soap:mode>REST</soap:mode> <soap:rest-http-method>GET</soap:rest-http-method> </jbi:provides> </jbi:services> </jbi:jbi> When receiving a JBI message on the activated JBI endpoint, the final address will be built from the JBI message payload.
<weat:getWeather xmlns:weat="http://petals.ow2.org/services/weather"> <citycode>FRXX0099</citycode> <unit>c</unit> </weat:getWeather> is associated with the address parameter value : http://weather.yahooapis.com/forecastrss?p={/*[localname()='getWeather'][1]/*[local-name()='citycode'] [1]}&u={/*[local-name()='getWeather'][1]/*[local-name()='unit'][1]} and produces the URI http://weather.yahooapis.com/forecastrss?p=FRXX0099&u=c.
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"> <channel> <title>Yahoo! Weather - Toulouse, FR</title> <link>http://us.rd.yahoo.com/dailynews/rss/weather/Toulouse__FR/*http://weather.yahoo.com/forecast/ FRXX0099_c.html</link> <description>Yahoo! Weather for Toulouse, FR</description> <language>en-us</language> <lastBuildDate>Thu, 06 Mar 2008 3:00 pm CET</lastBuildDate> <ttl>60</ttl> <yweather:location city="Toulouse" country="FR" region=""/> <yweather:units distance="km" pressure="mb" speed="kph" temperature="C"/> <yweather:wind chill="3" direction="310" speed="37"/> <yweather:atmosphere humidity="37" pressure="0" rising="0" visibility="999"/> <yweather:astronomy sunrise="7:22 am" sunset="6:50 pm"/> <image> <title>Yahoo! Weather</title> <width>142</width> <height>18</height> <link>http://weather.yahoo.com/</link> <url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url> </image> <item> <title>Conditions for Toulouse, FR at 3:00 pm CET</title> <geo:lat>43.61</geo:lat> <geo:long>1.45</geo:long> <link>http://us.rd.yahoo.com/dailynews/rss/weather/Toulouse__FR/*http://weather.yahoo.com/forecast/ FRXX0099_c.html</link> <pubDate>Thu, 06 Mar 2008 3:00 pm CET</pubDate> <yweather:condition code="28" date="Thu, 06 Mar 2008 3:00 pm CET" temp="8" text="Mostly Cloudy"/> <description> <![CDATA[<img src="http://l.yimg.com/us.yimg.com/i/us/we/52/28.gif" /><br /> <b>Current Conditions:</b><br /> Mostly Cloudy, 8 C<BR /><BR /> <b>Forecast:</b><BR /> Thu - Mostly Cloudy. High: 10 Low: 4<br /> Fri - Cloudy. High: 10 Low: 4<br /> <br /> <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Toulouse__FR/*http://weather.yahoo.com/forecast/ FRXX0099_c.html">Full Forecast at Yahoo! Weather</a><BR/> (provided by The Weather Channel)<br/>]]> </description> <yweather:forecast code="27" date="06 Mar 2008" day="Thu" high="10" low="4" text="Mostly Cloudy"/> <yweather:forecast code="26" date="07 Mar 2008" day="Fri" high="10" low="4" text="Cloudy"/> <guid isPermaLink="false">FRXX0099_2008_03_06_15_0_CET</guid> </item> </channel> </rss> Consume modeIn this sample, we are going to expose a JBI service as REST service. The Service Unit configuration which will be used is : todo Web Service Notificationstodo Intoductiontodo Create a WS-N topictodo Subscribe to WS-N producertodo Send a WS notification from a JBI messageWhen the petals-bc-soap component receives a JBI message on a topic-activated endpoint, it is transformed into a WS-notification message and published on the linked topic. As an example of SOAP notification message, if the JBI message payload is : <text>This is a sample of JBI message payload...</text> and if it is published on the 'TopicSample' topic, the SOAP body payload of the notification message will be : <wsnt:Notify> <wsnt:NotificationMessage> <wsnt:SubscriptionReference> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing"> http://127.0.0.1:8084/wsn-consumer/services/consumer </wsa:Address> </wsnt:SubscriptionReference> <wsnt:Topic Dialect="xsd:anyURI">TopicSample</wsnt:Topic> <wsnt:ProducerReference> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing"> http://127.0.0.1:8084/wsn-producer/services/producer </wsa:Address> </wsnt:ProducerReference> <wsnt:Message> <text>This is a sample of JBI message payload...</text> </wsnt:Message> </wsnt:NotificationMessage> </wsnt:Notify> SecurityIntroductionThe SOAP binding component provides WS security features through the Axis2 rampart module (http://ws.apache.org/rampart/). This module is based on Apache WSS4J (http://ws.apache.org/wss4j/), an implementation of the OASIS WS-security specification (http://www.oasis-open.org/committees/wss). This module is natively provided by the binding component since the 3.0 release. Securing JBI ServicesConfigurationIn order to enable WS-security, you must add specific extensions to the consumes section of the Service Unit. This configuration will tell Rampart which security mode to be applied. Here's an example of a jbi.xml providing a simple Rampart configuration, with UsernameToken and Timestamping authentification : <?xml version="1.0" encoding="UTF-8"?> <jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi" xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-4.0" xmlns:helloworld="http://petals.ow2.org/helloworld" xmlns:soap="http://petals.ow2.org/components/soap/version-3.1"> <!-- Import a Service into PEtALS or Expose a PEtALS Service => use a BC. --> <jbi:services binding-component="true"> <!-- Expose a PEtALS Service => consumes a Service. --> <jbi:consumes interface-name="helloworld:Helloworld" service-name="helloworld:HelloworldService" endpoint-name="HelloworldEndpoint"> <!-- CDK specific fields --> <petalsCDK:mep>InOut</petalsCDK:mep> <!-- SOAP specific fields --> <soap:address>UserPasswordSecuredService</soap:address> <soap:remove-root>false</soap:remove-root> <soap:mode>SOAP</soap:mode> <soap:modules>rampart</soap:modules> <soap:service-parameters> <![CDATA[ <parameter name="InflowSecurity"> <action> <items>UsernameToken Timestamp</items> <passwordCallbackClass> org.ow2.petals.usecase.soapsecurity.handler.RawCBHandler </passwordCallbackClass> </action> </parameter> ]]> </soap:service-parameters> </jbi:consumes> </jbi:services> </jbi:jbi> On this example, an Axis2 service will be created (MyExampleService) and is secured by a defined security handler :
package org.ow2.petals.usecase.soapsecurity.handler; import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class RawCBHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i]; String id = pwcb.getIdentifer(); if ("bob".equals(id)) { pwcb.setPassword("bobPW"); } } } } This class MUST be in the service classloader, the easiest way is to package it in the service unit. It will be handled by the SOAP binding component and the Rampart module.
The service is now secured with Rampart. If a SOAP message without security headers is handled by the service, a SOAP fault will be returned with message like: "Incoming message does not contain required Security header". Client sideThe SOAP header must contains the required security elements like in the following SOAP message snippet : <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-26598747"> <wsu:Created>2007-07-30T14:59:34.944Z</wsu:Created> <wsu:Expires>2007-07-30T15:04:34.944Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-6427893"> <wsse:Username>bob</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile- 1.0#PasswordDigest"> 0ziDIJ4Gd0XHbbbB/rgasDpOZJY= </wsse:Password> <wsse:Nonce> fqgz0lkb7/ezFiY7Km4qvg== </wsse:Nonce> <wsu:Created> 2007-07-30T14:59:34.944Z </wsu:Created> </wsse:UsernameToken> </wsse:Security> </soapenv:Header> The following code snippet shows how to engage the rampaet module on the client side and how to call the Web Service : ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(axis2ConfPath, null); ServiceClient client = new ServiceClient(ctx, null); OMElement payload = getSayHelloOMElement(sayHelloStr); Options options = new Options(); options.setProperty(WSSHandlerConstants.OUTFLOW_SECURITY, getOutflowConfiguration("bob")); client.engageModule(new QName("rampart")); options.setTo(targetEPR); options.setAction("sayHello"); client.setOptions(options); result = client.sendReceive(payload); The axis2ConfPath directory must point to a directory in which a modules directory contains the rampart-1.2.mar module used by the client. The code also uses a Class handler which is similar to the service's one, and will provide the required user and password : package org.ow2.petals.security.client.handler; import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class MyExampleClientHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i]; String id = pwcb.getIdentifer(); if ("bob".equals(id)) { pwcb.setPassword("bobPW"); } } } } In this example, the user name is sent in plain clear text in the request. Depending on your security needs, you should use a secured transport layer (such as HTTPS), or another Rampart configuration to encrypt the information (and even the body content if required). For more Rampart configuration examples, you should have a look at the samples provided by Apache in the rampart distribution at : http://www.apache.org/dyn/closer.cgi/ws/rampart/1_3. Using WS-PolicyThe Apache Rampart module is used to apply policies when calling an external Web Service (ie in consumer mode). The current section explains how to configure the component to use this feature. Configurationtodo UsageOnce the Service Unit is deployed on the SOAP Binding Component, all the JBI messages sent to the new activated endpoint are transformed into SOAP messages and the Web Service client will use the Service Unit defined policy to call the Web Service. The Web Service client behaviour is exactly the same as a policy-enabled Axis2 based Web Service client. An example of WS policy with PEtALS is provided in the PEtALS SOAP usecases at : http://websvn.ow2.org/listing.php?repname=petals&path=/trunk/configurations/petals-soap/petals-soap-policy/. SamplesThe SOAP binding component samples are available as packaged use cases. You can find them on trunk/configurations/petals-soap directory of the Petals ESB forge. Know problems"Transport out has not been set"If the exception message "Transport out has not been set" occurs when invoking an external web-service, using the petals-bc-soap, it can be due to a wrong URL of the external web-service. Please check it and retry your test. |
Table of contents
Contributors
No contributors found for: authors on selected page(s)
|