WSO2 ESB adding namespace to SOAP Envelope - soap

I need to add a new Namespace to the SOAP Envelope.
At the moment it's looking like that:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
But what I need is this:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
Maybe you can give me the code for the header mediator.
WSO2 ESB Documantation isn't working at the moment. I get a Synthax error there....

Use the XSLT mediator with the source attribute having the period value for its xpath. This will make the full SOAP message be processed by the XSLT template instead of the payload only.
<xslt key="yourXsltTemplate" source=".">

Using header mediator you can add soap headers not the namespace at envelope element AFAIK.
Anyway documentation should work.Please check. To add a namespace in the middle of sequence, you could use xslt mediator

Related

SOAP request with certain tags without namespace

Would be the following SOAP request valid according to the standard?
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns2:ServiceReq xmlns:ns2="http://www.tibco.com/service" xmlns:ns1="http://www.tibco.com/framework">
<ns1:HeaderIn>
<ns1:countryISO>FR</ns1:countryISO>
<ns1:callerDateTime>2021-11-26T15:50:08.742Z</ns1:callerDateTime>
</ns1:HeaderIn>
<ns2:request>
<entete>
<profile>Default</profile>
</entete>
<input>
<type>W</type>
<codeRegion>X</codeRegion>
</input>
</ns2:request>
</ns2:ServiceReq>
</soapenv:Body>
</soapenv:Envelope>
I am not sure because certain tags don't have a namespace
There are multiple levels of valid here:
Is it a valid SOAP message as per the SOAP standard? Yes. The SOAP envelope and body tags seem valid.
Is it a valid XML format? Yes, it's a well formed XML file.
Are those elements without a namespace prefix valid? Yes. Elements can be in a default namespace or in no namespace at all.
Is the actual content of the body a valid messages? You can only tell if you verify the message you posted against the expected message as defined in the WSDL file of the web service.
All the elements in the body of the SOAP message should belong to specific namespaces, but sometimes a developer forgets to add a namespace annotation on the element, or copy-pastes something from some place else, or whatever, and you end up with weird looking XMLs like that. The service works and the message is correctly parsed, but it just looks funny.

Passing encoded XML content in SOAP envelop request in Java application

I'm developing a Java application where I need to make a web service request using SOAP protocol. In that SOAP envelop request, one of the XML attribute/property called content will hold the XML file itself like below:-
<n1:envelope>
<message>
<id>67872894892424</id>
</message>
<sender agency="GS1" scheme="tGLK">ur.0</sender>
<recipients>
<id agency="GS1" scheme="tGLK">test</id>
</recipients>
<content encoding="XML" extension="A" format="ATTP">
------
----
</content></n1:envelope>
I'm new to it and requires some assistance in clarifying my doubts. I'm using JDK1.8 and Apache CXF. How can I do marshaling/unmarshalling for this particular content attribute? Normal SOAP envelops request is easy to do it but not sure how to pass an encoded XML itself in SOAP request. Is there any reference links? Thanks
Your case is an example of including XML inside XML. Yes, XML could be included inside an SOAP(XML), there are two ways, though both means almost same thing.
Using CDATA encoding
<hello><![CDATA[<El><E2><E3 attr="D1">Text</E3></E2></El>]]></hello>
Converting the XML into text by replacing, < with <, " with &quote; and > with >
<hello><El><E2><E3 attr="D1">Text</E3></E2></El></hello>
To
<hello>>El<>E2<>E3 attr="D1"<Text>/E3<>/E2<>/El<</hello>
Hence, to include the XML inside SOAP, while adding the XML element, you need to follow either approach while marshaling/unmarshaling.

How to create a SOAP message from JSON payload in mule

I need to transform the following json payload into a soap message and send the message to a consumer, the consumer edits the data and sends back the soap message.
I haven't done much in soap. I only have REST experience. what steps do I need to take in a process like this?
what is the best approach?
[{"salesOrderId":"00004-5-6","saleName":"House Sale","status":"processing"}, {"salesOrderId":"00001-2-3","saleName":"Car Sale","status":"processing"}]
There are various way to perform this transformation, for example:
PATH - 1
Json To XML (with transformer or string set payload)
Xml To SOAP Request using XSLT, transformer or string set payload.
Send SOAP Request sobre HTTP (POST / Content-type: applicacion/xml / soapAction)
PATH - 2
Json To SOAP Request using Groovy, XSLT or string set payload.
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
PATH - 3
Json To SOAP Request Proxy (WSDL To Java).
Send SOAP Request sobre HTTP-OUTBOUND (POST / Content-type: applicacion/xml / soapAction)
The easiest way of doing it is extract the JSON elements from the JSON payload by using <json:json-to-object-transformer/>and store each node value in variables like flow variable in Mule.
Then You can create the SOAP request using XSLT and passing the flow variables value into XSLT as <mulexml:context-property/>
ref:- https://developer.mulesoft.com/docs/display/current/XSLT+Transformer
Once your SOAP XML is created, you can simply post them to your HTTP outbound endpoint pointing to your external web service you need to consume
Try using Mule DataMapper. That helps you to convert a JSON to XML in the more easier way. You can try it in Anypoint Studio of Mule.

SOAPUI Extract data from SOAP Response and use in REST request

I have been looking at the answer to this question:
Pulling details from response to new request SoapUI
which is similar to what I am looking for but I can't get it to work.
I have a small SOAPUI testsuite and I need to extract a value from the response of a SOAP request and then use this value in a subsequent REST request.
The response to my SOAP request is:
<ns0:session xmlns:ns0="http://www.someurl.com/la/la/v1_0">
<token>AQIC5wM2xAAIwMg==#</token>
</ns0:session>
so I need the token to use in my REST request. I know it involves using Property Transfer and some XPath / XQuery but I just can't get it right. At the moment my property transfer window points to Source: SOAP test Property: Response and has data(/session/token/text()) in the text box. In target it has Target: REST testcase Property: newProp and I have Use XQuery checked.
Any help greatly appreciated.
Thanks,
Adrian
I think you just need to declare the namespace ns0 and use it in the XPath. Also, uncheck the XQuery, it is only used when you are using XQuery, not XPath.
Replace your expression with this:
declare namespace ns0='http://www.someurl.com/la/la/v1_0';
/ns0:session/token/text()

SOAP Action WSDL

I'm trying to implement a client for National Rail Enquiries' SOAP Service (http://www.livedepartureboards.co.uk/ldbws/).
I stick the WSDL (http://realtime.nationalrail.co.uk/ldbws/wsdl.aspx) into http://soapclient.com/soaptest.html, but I get back the error message "Unable to handle request without a valid action parameter. Please supply a valid soap action."; what on earth should the action be?
Thanks,
Stewart
edit:
I just used soapclient.com as a quick example. In my software, I send the following XML; I still get that I'm missing an action.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://thalesgroup.com/RTTI/2008-02-20/ldb/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/types" xmlns:ldbt="http://thalesgroup.com/RTTI/2007-10-10/ldb/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ct="http://thalesgroup.com/RTTI/2007-10-10/ldb/commontypes" >
<SOAP-ENV:Body>
<ldbt2:GetDepartureBoardRequest xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/" >
<ldbt2:numRows>5</ldbt2:numRows>
<ldbt2:crs>WAT</ldbt2:crs>
<ldbt2:filterCrs>GLD</ldbt2:filterCrs>
<ldbt2:filterType>to</ldbt2:filterType>
<ldbt2:timeOffset>0</ldbt2:timeOffset>
</ldbt2:GetDepartureBoardRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If its a SOAP 1.1 service then you will also need to include a SOAPAction HTTP header field:
http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
I have come across exactly the same problem when trying to write a client for the National Rail SOAP service with Perl.
The problem was caused because the Perl module that I'm using 'SOAP::Lite' inserts a '#' in the SOAPAction header ...
SOAPAction: "http://thalesgroup.com/RTTI/2008-02-20/ldb/#GetDepartureBoard"
This is not interpreted correctly by .NET servers. I found this out from Example 3-19 in O'Reilly's Programming Web Services with SOAP . The solution was given below in section 3-20, namely you need to explicitly specify the format of the header with the 'on_action' method.
print SOAP::Lite
-> uri('urn:Example1')
-> on_action(sub{sprintf '%s/%s', #_ })
-> proxy('http://localhost:8080/helloworld/example1.asmx')
-> sayHello($name)
-> result . "\n\n";
My guess is that soapclient.com is using SOAP::Lite behind the scenes and so are hitting the same problem when talking to National Rail.
The solution is to write your own client so that you have control over the format of the SOAPAction header ... but you've probably done that already.
SOAPAction is required in SOAP 1.1 but can be empty ("").
See https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
"The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI."
Try setting SOAPAction=""
When soapAction is missing in the SOAP 1.2 request (and many clients do not set it, even when it is specified in WSDL), some app servers (eg. jboss) infer the "actual" soapAction from {xsd:import namespace}+{wsdl:operation name}.
So, to make the inferred "actual" soapAction match the expected soapAction, you can set the expected soapAction to {xsd:import namespace}+{wsdl:operation name} in your WS definition (#WebMethod(action=...) for Java EE)
Eg. for a typical Java EE case, this helps (not the Stewart's case, National Rail WS has 'soapAction' set):
#WebMethod(action = "http://packagename.of.your.webservice.class.com/methodName")
If you cannot change the server, you will have to force client to fill soapAction.
I've just spent a while trying to get this to work an have a written a Ruby gem that accesses the API. You can read more on it's project page.
This is working code in Ruby:
require 'savon'
client = Savon::Client.new do
wsdl.document = "http://realtime.nationalrail.co.uk/LDBWS/wsdl.aspx"
end
response = client.request 'http://thalesgroup.com/RTTI/2012-01-13/ldb/GetDepartureBoard' do
namespaces = {
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}
soap.xml do |xml|
xml.soap(:Envelope, namespaces) do |xml|
xml.soap(:Header) do |xml|
xml.AccessToken do |xml|
xml.TokenValue('ENTER YOUR TOKEN HERE')
end
end
xml.soap(:Body) do |xml|
xml.GetDepartureBoardRequest(xmlns: "http://thalesgroup.com/RTTI/2012-01-13/ldb/types") do |xml|
xml.numRows(10)
xml.crs("BHM")
xml.filterCrs("BHM")
xml.filterType("to")
end
end
end
end
end
p response.body
Hope that's helpful for someone!
We put together Web Services on Windows Server and were trying to connect with PHP on Apache. We got the same error. The issue ended up being different versions of the Soap client on the different servers. Matching the SOAP versions in the options on both servers solved the issue in our case.
the service have 4 operations:
1. GetServiceDetails
2. GetArrivalBoard
3. GetDepartureBoard
4. GetArrivalDepartureBoard
I have solved this problem, in Java Code, adding:
MimeHeaders headers = message.getMimeHeaders();
headers.addHeader("SOAPAction", endpointURL);