SOAP mediation Wso2 ESB - soap

Hello I have the following message:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-11">
<wsu:Created>2012-09-06T09:59:04.031Z</wsu:Created>
<wsu:Expires>2012-09-06T10:04:04.031Z</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-12">
<wsse:Username>admin</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">admin</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body />
</soapenv:Envelope>
I wanted to use an XPath to get the username <wsse:Username>admin</wsse:Username> from the incoming message
any suggestion?
EDIT:
I tried this:
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="p1" expression="$header/wsse:Username" scope="default" />
<log>
<property name="output*********" expression="get-property('p1')" />
</log>
</inSequence>
but it does not output the username:
MessageID: urn:uuid:68f95493-7dfd-416a-b
455-f77f4fd5c9c5, Direction: request, output********* =

Nuvio,
You can use the expression "$header/wsse:Security" where "wsse" prefixes the namespace carried by the Security header element. Shown below is how you can get it saved to a Synapse message context property.
<property xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="Security" expression="$header/wsse:Security" />
FYI, you can use the syntax "$header/header_name" to extract any SOAP header element that exists in your SOAP message.
Hope this helps!
Cheers,
Prabath

otherwise you have option to get it use this xpath:"//wsse:Username/text()"
I think it will help you i am also new for this wso2 tool.
hope this carry you..

Related

How to retrieve Sabre profile using SOAP API

I'm trying to use the Sabre SOAP API to retrieve a profile. I'm using the SOAP template here (https://developer.sabre.com/guides/travel-agency/developer-guides/soap-apis-request-format) with the specifics here (https://developer.sabre.com/sabre_hospitality/apis/soap_apis/hotel/profile/read_profile). I'm able to get a BinarySession token ok using the SessionCreateRQ request ok. It starts with the text "Shared/IDL:IceSess/SessMgr".
My request looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Header>
<eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="1.0">
<eb:From>
<eb:PartyId />
</eb:From>
<eb:To>
<eb:PartyId />
</eb:To>
<eb:CPAId>ipcc</eb:CPAId>
<eb:ConversationId>conversationID</eb:ConversationId>
<eb:Service>OTA_ReadRQ</eb:Service>
<eb:Action>OTA_ReadRQ</eb:Action>
<eb:MessageData>
<eb:MessageId>mid:20001209-133003-2333#clientofsabre.com</eb:MessageId>
<eb:Timestamp>2001-02-15T11:15:12Z</eb:Timestamp>
<eb:TimeToLive>2001-02-15T11:15:12Z</eb:TimeToLive>
</eb:MessageData>
</eb:MessageHeader>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:BinarySecurityToken valueType="String" EncodingType="wsse:Base64Binary">MY SECURITY TOKEN GOES HERE</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<eb:SoapAPIServiceActionCode>
<OTA_ReadRQ Version="1" EchoToken="1122" PrimaryLangID="en" xmlns="http://www.opentravel.org/OTA/2003/05">
<ReadRequests>
<ProfileReadRequest>
<UniqueID Type="1" ID="14EF985B2C" ID_Context="crs">
<CompanyName CodeContext="hotel" Code="10001"/>
</UniqueID>
</ProfileReadRequest>
</ReadRequests>
</OTA_ReadRQ>
</eb:SoapAPIServiceActionCode>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But when I do this I get the error:
<soap-env:Fault>
<faultcode>soap-env:Client.InvalidAction</faultcode>
<faultstring>Action specified in EbxmlMessage does not exist.</faultstring>
<detail>
<StackTrace>com.sabre.universalservices.base.exception.ApplicationException: errors.xml.USG_INVALID_ACTION</StackTrace>
</detail>
</soap-env:Fault>
Can anyone advise where I'm going wrong?
Try to use <eb:Action>OTA_ProfileReadRQ</eb:Action> instead.
Sabre responds with OTA_ProfileReadRS, so I suppose the Action code may contain "ProfileRead" as well.
First of all you must have permission in your iPCC/EPR the authorization to use this service.
The faultstring="Action specified in EbxmlMessage does not exist." error was in <eb:Action>OTA_ReadRQ</eb:Action>.
You can read more details about the hospitallity services in:
https://github.com/SabreDevStudio/get-hotel-avail-v2-sample-nodejs
https://github.com/SabreDevStudio/get-hotel-details-sample-nodejs
https://github.com/SabreDevStudio/hotel-price-check-v2-sample-nodejs

WSO2 ESB 5.0 How to recover value xml element into cdata section?

Hello WSO2 ESB community,
We are new in WSO2. We need help to resolve this question.
We've developed a proxy which receives a soap message like this.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:es="http://es.ata">
<soapenv:Header></soapenv:Header>
<soapenv:Body>
<es:rc>
<es:xml><![CDATA[<message date="2017-03-02" id="ATA001">.....</message>]]></es:xml>
<es:rc>
</soapenv:Body>
</soapenv:Envelope>
How can we recover the attribute value "id"??
Anyone can help us??
Thanks in advance.
Extract es:xml content in a property type OM (XML) and use XPath inside this content.
Send your payload to this sample proxy and have a look to wso2-esb-service.log, you will find "id = ATA001"
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" startOnLoad="true" trace="disable">
<description/>
<target>
<inSequence>
<property xmlns:es="http://es.ata" name="CDATAPAYLOAD" expression="$body/es:rc/es:xml" type="OM"/>
<property name="ID_VALUE" expression="get-property('CDATAPAYLOAD')/#id"/>
<log level="custom">
<property name="id" expression="get-property('ID_VALUE')"/>
</log>
</inSequence>
</target>
</proxy>

Access a web-service with session-key/token from WSO2 ESB

I'm starting to evaluate WSO2 ESB and try to implement some simple but real life scenarios.
What I'm trying to do, in this specific case is connect to a web-service that uses a session-key in the payload to do the authentication. So there is one web-service call with user and password to get the key and then I need to put this into the payload of the second web-service call to actually retrieve data from a service.
I don't want to log in with every service call, for performance reasons, but log in once, store the key for some time and do a couple of requests.
The service I want to call is a SugarCRM web-service.
The login message would be something like this:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sug="http://www.sugarcrm.com/sugarcrm" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<sug:login soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<user_auth xsi:type="sug:user_auth">
<user_name xsi:type="xsd:string">interface</user_name>
<password xsi:type="xsd:string">MD5HASHOFPASSWORD</password>
</user_auth>
<application_name xsd:string">dummy</application_name>
<name_value_list xsi:type="sug:name_value_list" soapenc:arrayType="sug:name_value[]"/>
</sug:login>
</soapenv:Body>
Which returns something like this:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.sugarcrm.com/sugarcrm">
<SOAP-ENV:Body>
<ns1:loginResponse xmlns:ns1="http://www.sugarcrm.com/sugarcrm">
<return xsi:type="tns:entry_value">
<id xsi:type="xsd:string">loggfi0i3j6eeugs7l0a0m2587</id>
</return>
</ns1:loginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Then I need to use the "id" field as the token for a new request.
Example, to request all the Leads (the "id" is put into the "session" field):
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sug="http://www.sugarcrm.com/sugarcrm" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<sug:get_entry_list soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<session xsi:type="xsd:string">loggfi0i3j6eeugs7l0a0m2587</session>
<module_name xsi:type="xsd:string">Leads</module_name>
</sug:get_entry_list>
</soapenv:Body>
</soapenv:Envelope>
This request then returns all the Leads in the database.
Equally this is needed for accessing web-services that use OAuth2, for example the REST-API of MS Dynamics CRM, only then I need to put the token/bearer in the header.
How would I go about realizing the above scenario in WSO2 ESB? I'm sure this is pretty common, but I have not found documentation or examples for it.
Here is the sequence to get the session-id from the CRM:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="sugar_login" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<sug:login xmlns:sug="http://www.sugarcrm.com/sugarcrm">
<sug:user_auth>
<user_name>interface</user_name>
<password>MD5HASHOFPASSWORD</password>
<version>1</version>
</sug:user_auth>
<application_name>dummy</application_name>
</sug:login>
</format>
</payloadFactory>
<header name="To" value="http://my.sugarcrm.com:9090/service/v4_1/soap.php"/>
<call>
<endpoint name="templEPTimeout" template="org.wso2.carbon.connector.sugarcrm.timeout">
<axis2ns653:parameter name="timoutDuration" value="6000" xmlns:axis2ns653="http://ws.apache.org/ns/synapse"/>
<axis2ns654:parameter name="maximumDuration" value="3000" xmlns:axis2ns654="http://ws.apache.org/ns/synapse"/>
<axis2ns655:parameter name="progressAFactor" value="2.0" xmlns:axis2ns655="http://ws.apache.org/ns/synapse"/>
<axis2ns656:parameter name="initialDuration" value="2000" xmlns:axis2ns656="http://ws.apache.org/ns/synapse"/>
</endpoint>
</call>
<!-- Remove response custom header information -->
<header action="remove" name="X-SOAP-Server" scope="transport"/>
<header action="remove" name="Cache-control" scope="transport"/>
<header action="remove" name="Vary" scope="transport"/>
<header action="remove" name="Expires" scope="transport"/>
<header action="remove" name="Set-Cookie" scope="transport"/>
<header action="remove" name="path" scope="transport"/>
<property expression="//ns1:loginResponse/return/id"
name="sugarsessionid" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
</sequence>
You can use the sugarcrm connector to connect with SugarCRM API. You can find the sugarcrm connector at WSO2 Store. Find more details in the documentation.

WSO2 ESB adding prefix to header

I try to use the WSO2 ESB with the SAP Solution Manager Webservice as an endpoint.
For sending a message to the Webservice I need to modify the SOAP Header.
While searching with google I found out that I could use the Enrich Mediator for this. But I couldn't find an example how to add the prefix to the header.
What I have is this:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<urn:ReadCompleteIncident>
<IncidentGuid>xxxxx</IncidentGuid>
<SystemGuid>xxx</SystemGuid>
</urn:ReadCompleteIncident>
</soapenv:Body>
</soapenv:Envelope>
But I get an error because the ESB doesn't know the prefix "urn:". So I have to add "xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style"" to the Header for getting this:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
<soapenv:Body>
<urn:ReadCompleteIncident>
<IncidentGuid>xxxxx</IncidentGuid>
<SystemGuid>xxx</SystemGuid>
</urn:ReadCompleteIncident>
</soapenv:Body>
</soapenv:Envelope>
How can I do this with the Enrich Mediator? Or is there another solution?
Thank you :)
You can use the Header mediator of WSO2 ESB to achieve your requirement.
<header name="Action" value="urn:ReadCompleteIncident"/>
You can refer this link to find more information.
http://docs.wso2.org/wiki/display/ESB460/Header+Mediator
I solved this problem with Enrich Mediator. For example, here is my proxy.
Input message to ESB:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<content>Message content</content>
</soap:Body>
</soap:Envelope>
Required Input message to SAP PI:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xxxx">
<soapenv:Header/>
<soapenv:Body>
<urn:xxxx>
<content>Message content</content>
</urn:xxxx>
</soapenv:Body>
</soapenv:Envelope>
Solution:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="WSO2toSAP"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<property name="FORCE_SC_ACCEPTED"
value="true"
scope="axis2"
type="STRING"/>
<log level="full"/>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="INPUT_MESSAGE"/>
</enrich>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body/>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source type="inline" clone="true">
<urn:xxxx xmlns:urn="urn:xxxx"/>
</source>
<target type="body"/>
</enrich>
<enrich>
<source type="property" clone="true" property="INPUT_MESSAGE"/>
<target type="body" action="child"/>
</enrich>
<log level="full"/>
<send>
<endpoint key="WSO2toSAP_endpoint"/>
</send>
</inSequence>
</target>
<description/>
</proxy>
I hope, that I help you :)
I think there are multiple ways you can solve this problem -
payloadFactory mediator to manipulate the request or response.
using script mediator - check this page http://abeykoon.blogspot.com/2013/03/encoding-and-decoding-xml-using-wso2-esb.html#comment-form for more details on how to use the script. As you can see, the blogger is generating the request using payloadFactory and then manipulate it using the scripts to get the desired effect.
If I find time, I will try to build a quick solution for you using the scripts.
All the best..

Add User and Pass to SOAP Header in Mule

It seems this should be simple but the solution has been eluding me. My flow is XML -> XSLT translation -> consume web service (IBM Web Sphere Web Service to be specific). I have the pieces working individually but I am having trouble figuring out how to add user/pass to the SOAP header. I would think that I should be able to add them to the keys in the security tab on the Mule SOAP Component (I have the operation set to Proxy Client). Unfortunately, I cannot figure out what the valid keys are. Maybe I am way off base even attempting to use the security tab. So ultimately I need my outgoing XML to contain:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>
myUserName
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
myPa33W0rd
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
Currently my Mule flow is putting out:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
Do I need to add the security information manually (maybe in the XSLT translation)? That doesn't feel right but I can't figure out how to add it.
Here are the relevant lines from my flow:
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="src\main\resources\MappingMapToChangeCatalogEntry.xslt" outputEncoding="US-ASCII" doc:name="XSLT"/>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
In order to add WS-Sec you need to configure the CXF WSS4J interceptors and inject them into Mule's CXF message processors.
Pre 3.3 =
<spring:bean name="wss4jOutConfiguration"
class="org.springframework.beans.factory.config.MapFactoryBean">
<spring:property name="sourceMap">
<spring:map>
<spring:entry key="action" value="Signature" />
<spring:entry key="user" value="joe" />
<spring:entry key="signaturePropFile" value="org/mule/module/cxf/wssec/wssecurity.properties" />
<spring:entry key="passwordCallbackClass" value="org.mule.module.cxf.wssec.ClientPasswordCallback" />
</spring:map>
</spring:property>
</spring:bean>
...
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP">
<cxf:outInterceptors>
<spring:bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<spring:property name="properties" ref="wss4jOutConfiguration"/>
</spring:bean>
</cxf:outInterceptors>
</cxf:proxy-client>
Rough Sample Password Callback class:
public class ClientPasswordCallback implements CallbackHandler{
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback callback = (WSPasswordCallback) callbacks[0];
if(callback.getIdentifier().equals("joe")){
callback.setPassword("pass");
}
}
See more here: http://www.mulesoft.org/documentation/display/current/WS-Security+Usability+Improvement
3.3.+ :
There is a new cxf:ws-security element availble in 3.3+ Here is an example flow here: https://svn.codehaus.org/mule/tags/mule-3.4-M2/modules/cxf/src/test/resources/org/mule/module/cxf/wssec/cxf-secure-proxy-flow.xml
<cxf:proxy-client payload="body"
enableMuleSoapHeaders="true" doc:name="SOAP">
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action"
value="UsernameToken
Timestamp" />
<cxf:property key="user" value="joe" />
<cxf:property key="passwordCallbackClass"
value="com.mulesoft.mule.example.security.PasswordCallback" />
<cxf:property key="mustUnderstand" value="false" />
</cxf:ws-config>
</cxf:ws-security>
</cxf:proxy-client>
Previously I have also just handled he entire envelope myself when using XSLT. I have then passed the user and pass into the XSLT via context params
<xm:xslt-transformer xsl-file="xslt/ToSomethingSOAPY.xsl">
<xm:context-property key="user" value="${my.user}" />
<xm:context-property key="password" value="${my.pass}" />
</xm:xslt-transformer>
And then reieived them via xsl params like so:
<xsl:param name="user" />
....
<wsse:UsernameToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="UsernameToken-1018444980">
<wsse:Username><xsl:value-of select="$user" /></wsse:Username>