How To Preserve SOAP Headers to use with Mule 4 Web Service Consumer? - soap

I have used an Existing WSDL to create an Experience API where I am performing several steps before either:
Passing the SOAP Request Message as-is to the Original Backend System using Mule4 Web Service Consumer or
Calling another Backend System (RESTful API) and transforming the Response to match the Expected SOAP Response Message
Sample Message
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="urn:Acme/PublicService/V1" xmlns:ns0="urn:/Acme/BasicDataPublicService/V1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header>
<a:Action s:mustUnderstand="1" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">urn:Acme/PublicService/V1/PublicService/SetCustomer</a:Action>
<a:MessageID xmlns:a="http://www.w3.org/2005/08/addressing">urn:uuid:4afe0693-adea-4ede-bec9-10b694708d85</a:MessageID>
<a:ReplyTo xmlns:a="http://www.w3.org/2005/08/addressing">
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo8KxyyGpakdIj8o84JOeAMsAAAAAQBkt3vfAK0C4dDgn3rAKx/iXgqYosnhKv/OHgph9cXoACQAA</VsDebuggerCausalityData>
<a:To s:mustUnderstand="1" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">http://316.820.517.311:36990/PublicInterface/Service</a:To>
<AuthorizationToken xmlns="urn:Acme/Authorization/V1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CultureName>uk-UK</CultureName>
<OnBehalfOf i:nil="true"></OnBehalfOf>
<Password>****</Password>
<UserName>sa-ACME</UserName>
</AuthorizationToken>
</env:Header>
<env:Body>
<ns:SetCustomer>Muli-Tier Message</ns:SetCustomer>
</env:Body>
</env:Envelope>
According to Mulesoft KB; this requires additional Transformation steps in the beginning of the flow. Passing the SOAP Body is not an issue; the SOAP Header is a pickle, however. Especially since the KB document is hard-coding the values; while in my case these need to be dynamic (i.e. coming from the Original SOAP Request message).
I tried mapping the Header Parameters to a Variable as described but I cannot seem to get to it.
Option 1 Mapping the Header Elements to Children Attributes of a Variable, results in the Variable Storing Null
%dw 2.0
output application/xml writeDeclaration=false, writeNilOnNull=true
ns ns0 http://www.w3.org/2005/08/addressing
ns s http://www.w3.org/2003/05/soap-envelope
---
headers: {
ns0#Action #(s#mustUnderstands: payload.headers.Action.#mustUnderstands): payload.headers.Action as String default null,
ns0#MessageID: payload.headers.MessageID as String default null,
ns0#ReplyTo: {
ns0#Address: payload.headers.ReplyTo.Address as String default null
},
VsDebuggerCausalityData: payload.headers.VsDebuggerCausalityData as String default null,
ns0#To #(s#mustUnderstands: payload.headers.To.#mustUnderstands): payload.headers.To as String default null,
AuthorizationToken: {
CultureName: payload.headers.AuthorizationToken.CultureName as String default null,
OnBehalfOf: payload.headers.AuthorizationToken.OnBehalfOf as String default null,
Password: payload.headers.AuthorizationToken.Password as String default null,
UserName: payload.headers.AuthorizationToken.UserName as String default null
}
}
Option 2 Mapping payload.headers to a Variable, results in extra tags; and losing the XML Tag attributes
%dw 2.0
output application/xml writeDeclaration=false, writeNilOnNull=true
ns ns0 http://www.w3.org/2005/08/addressing
ns s http://www.w3.org/2003/05/soap-envelope
---
headers: payload.headers

It seems there is an issue with the WebService Consumer connector when generating the SOAP Envelope Header.
Instead of using the WebService Consumer Connector, try using an HTTP Request Connector passing the payload as-is.

I will come back and add more details on the answer, but here is how to solve that issue:
%dw 2.0
output application/xml writeDeclaration=false, writeNilOnNull=true
---
headers: (payload.headers.headers mapObject (value, key) -> {
(value)
})

Related

Perl: Connecting to Walmart API to load items Unsupported Media type error

We are trying using the marketplace.walmartapis.com api to bulk list items and it is returning unsupported media type for xml item feed
We are using Perl and are able to perform other commands to update inventory and pricing, check orders, lookup feeds and skus etc. The token SHOULD be good, as we ran two calls back to back using the same token and the first call (item inventory) worked as expected before trying to send the xml file. It is only when we try to send the xml batch file that we run into the problem.
We assume the issue is with the header/authentication and have tried many different combinations. But obviously we are missing something.
What is being sent:
POST https://marketplace.walmartapis.com/v3/feeds?feedType=item HTTP/1.1
Headers:
Authorization: Basic MDc4......
Content-Length: 2277
Accept: application/xml
Content-Type: multipart/formdata
Host: marketplace.walmartapis.com
WM_QOS.CORRELATION_ID: TB123456V32
WM_SEC.ACCESS_TOKEN: eyJra...
WM_SVC.NAME: Walmart Marketplace
Boundary: 1234ran4321dom5678boundary
formdata payload:
--1234ran4321dom5678boundary
Content-Disposition: formdata; name="xml"
Content-length: 2151
<?xml version="1.0" encoding="UTF-8"?>
<MPItemFeed xmlns="http://walmart.com/">
<MPItemFeedHeader>
<version>3.1</version>
<requestBatchId>......</requestBatchId>
<feedDate>2019-02-18T19:45:17</feedDate>
<mart>WALMART_US</mart>
</MPItemFeedHeader>
<MPItem>
<processMode>CREATE</processMode>
<sku>....</sku>
<productIdentifiers>
<productIdentifier>
<productIdType>UPC</productIdType>
<productId>..........</productId>
</productIdentifier>
</productIdentifiers>
<MPProduct>
<productName>.....................</productName>
<category>
<SportAndRecreation>
<SportAndRecreationOther>
<shortDescription>........................</shortDescription>
<keyFeatures>
<keyFeaturesValue>I...............</keyFeaturesValue>
</keyFeatures>
<brand>............</brand>
<manufacturer>.............</manufacturer>
<manufacturerPartNumber>.............</manufacturerPartNumber>
<modelNumber>..</modelNumber>
<mainImageUrl>............</mainImageUrl>
<count>1</count>
<isProp65WarningRequired>No</isProp65WarningRequired>
<sportsLeague>
<sportsLeagueValue>....</sportsLeagueValue>
</sportsLeague>
<keywords>................</keywords>
<isMemorabilia>......</isMemorabilia>
<isCollectible>...........</isCollectible>
</SportAndRecreationOther>
</SportAndRecreation>
</category>
</MPProduct>
</MPOffer>
<price>21.95</price>
<StartDate>2019-02-23T19:45:17</StartDate>
<EndDate>2019-04-19T19:45:17</EndDate>
<ShippingWeight>
<measure>2</measure>
<unit>lb</unit>
</ShippingWeight>
<ProductTaxCode>2038345</ProductTaxCode>
</MPOffer>
</MPItem>
</MPItemFeed>
--1234ran4321dom5678boundary--
back from Walmart.pm
$HASH = {
"error" => {
"category" => "DATA",
"causes" => {},
"code" => "UNSUPPORTED_MEDIA_TYPE.GMP_GATEWAY_API",
"errorIdentifiers" => {},
"info" => "Unsupported Media Type.",
"severity" => "ERROR"
},
"xmlns:ns2" => "http://walmart.com/"
};
Any pointers in the right direction would be appreciated.
Thanks for everyone that looked. The problem seems to be solved
It was one minor typo
multipart/formdata needed to be multipart/form-data
With that change now we are getting a feed id that shows up in the Seller area

Azure media service job creation fails using rest api

Trying to consume Azure media service rest api. (following the tutorial : https://learn.microsoft.com/en-us/azure/media-services/media-services-rest-get-started)
Everything works fine until the point I try to create a Job. Sending the same request as in example (except asset id and token) and getting response :
Parsing request content failed due to: Make sure to only use property names that are defined by the type
Request:
POST https://wamsdubclus001rest-hs.cloudapp.net/api/Jobs HTTP/1.1
Connection: Keep-Alive
Content-Type: application/json
Accept: application/json; odata=verbose
Accept-Charset: UTF-8
Authorization: Bearer token -> here i send real token
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
x-ms-version: 2.11
Content-Length: 458
Host: wamsdubclus001rest-hs.cloudapp.net
{
"Name":"TestJob",
"InputMediaAssets":[
{
"__metadata":{
"uri":"https://wamsdubclus001rest-hs.cloudapp.net/api/Assets('nb%3Acid%3AUUID%3A5168b52a-68ed-4df1-bac8-0648ce734ff6')"
}
}
],
"Tasks":[
{
"Configuration":"Adaptive Streaming",
"MediaProcessorId":"nb:mpid:UUID:ff4df607-d419-42f0-bc17-a481b1331e56",
"TaskBody":"<?xml version=\"1.0\" encoding=\"utf-8\"?><taskBody><inputAsset>JobInputAsset(0)</inputAsset> <outputAsset>JobOutputAsset(0)</outputAsset></taskBody>"
}
]
}
Response:
{
"error":{
"code":"",
"message":{
"lang":"en-US",
"value":"Parsing request content failed due to: Make sure to only use property names that are defined by the type"
}
}
}
It seems to be related with __metadata property. when I follow instruction from here : Creating Job from REST API returns a request property name error, the error changes:
"error":{
"code":"",
"message":{
"lang":"en-US",
"value":"Invalid input asset reference in TaskBody - "
}
}
}
Cant figure out whats wrong, thanks
Let me check on this, but it could be a couple issues that I have run into in the past.
First. Set both the Accept and Content-Type headers to:
"application/json; odata=verbose"
Next, double check that you are actually using the long underscore character on the metadata property. I've had issues where that was sending the wrong underscore character and it didn't match the property name.
Let me know if either of those helps.
It seems the issue was about "Content-Type". As I am using .net Core it was not easy to set the Conent-type as "application/json; odata=verbose".
1) Tried with RestSharp - dosnt support it, it cuts "odata=verbose" part out
2) Tried with Systsem.Net.Http.HttpClient -> Possible but difficult.
To add it as "Accept" :
MediaTypeWithQualityHeaderValue mtqhv;
MediaTypeWithQualityHeaderValue.TryParse("application/json;odata=verbose", out mtqhv);
client.DefaultRequestHeaders.Accept.Add(mtqhv);//ACCEPT header
To add it as "Content-Type" :
request.Content = new StringContent(content,
System.Text.Encoding.UTF8); //CONTENT-TYPE header -> default type will be text/html
request.Content.Headers.Clear(); // need to clear it - it will fail otherwise
request.Content.Headers.TryAddWithoutValidation("Content-Type","application/json;odata=verbose");

Call soap web-service in mobilefirst hybrid app

I'm attempting to call SOAP Web-Service in hybrid app. How should I form SOAP message correctly if the back-end service displays the next error in log:
Caused by: com.ibm.websphere.security.WSSecurityException: Exception
org.apache.axis2.AxisFault: CWWSS7509W: The received SOAP request
message is rejected becasue it does not correctly specify SOAP action
and WS-Addressing action while there is at least one PolicySet
attachment at operation level of the
TestServiceService.TestServicePort service. ocurred while running
action:
com.ibm.ws.wssecurity.handler.WSSecurityConsumerHandler$1#9b5addf6 at
com.ibm.ws.security.context.ContextImpl.runWith(ContextImpl.java:394)
at
com.ibm.ws.wssecurity.platform.websphere.auth.WSSContextImpl.runWith(WSSContextImpl.java:65)
... 35 more
This is content of js file in adapter
function getToken(){
var token = WL.Server.getActiveUser().attributes.LtpaToken;
var fulltoken = "LtpaToken2=" + token;
return fulltoken;
}
function callService(){
WL.Logger.warn("INSIDE callService "+getToken());
var path="checkauth/TestServiceService";
var request=
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://provider.ws/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:callService />
</soapenv:Body>
</soapenv:Envelope>;
var input = {
method : 'post',
returnedContentType : 'xml',
path : path,
body: {
content: request.toString(),
contentType: 'text/xml; charset=utf-8',
},
headers: {"Cookie": getToken()}
};
var result= WL.Server.invokeHttp(input);
return result;
}
This is SOAP Envelope which was displayed via TCP/IP Monitor:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<s:Security xmlns:s="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:w2="http://www.ibm.com/websphere/appserver/tokentype" soapenv:mustUnderstand="1">
<u:Timestamp>
<u:Created>2015-08-10T13:18:56.644Z</u:Created>
</u:Timestamp>
<s:BinarySecurityToken ValueType="w2:LTPAv2" u:Id="ltpa_20">dt8G5gZ9PpZ/Ea5oXr6EQd8dpmfXKiqeXiShPlpSWntK59hUzyoDNX9TKq1nFLfxUEJyJdjMxoG7EVxw8Q1zhyZdYhTXnsMkNVqScvSsPpX7ln/ad+/WAHqaaFymD8XtVEsjOlezQDarPaUmnKAQRUSrLkRnL5B1MoCclTe129Oojg8o+hACgDKjuvPnvL8jaf45wNiou6Il5ZOayBcoHpNehI7i2hADa4fTKzX/T69OPnsZOyWYrNosdezNd24b61vs85k2YK26rLTp5dkEp8f3mwKZBwOOK4z1wQdiAXJf6kQvzR22SfFitbJA5MStlBcovHAvB5T+J5Ip80/kI5BPa2ogoufd9HZAdKTNII8cHpHBN2Ub/+atzg1L7EhIWuzO1BPI62KoU/hPqAHn3uGCGrbIILesKx0TPvlgmU4Bg54H9prC0I8hgXbO1HLuz4M5DNE5ASFbH0W3LJ/UU7BGXJs6iJmfAfJtQ+ip5ZFHlLItZA+ca2LkVWmyD/xKVxyxHE1uDz8zV/CfV9Km0T+8FTA0Cfi/PIb5KiAagdrmqtw6GuJDbSCsC3sdh21G/cA3Y0p/f+rhDw8m/e17y1cEuq9HOBharwn7ET3wO30V4D4rGoLhd4QsN6X1z89gZmZVaI6J9urpPAEiSndmyQ==</s:BinarySecurityToken>
</s:Security>
<wsa:To>http://X.X.X.X:9082/checkauth/TestServiceService</wsa:To>
<wsa:MessageID>urn:uuid:5d1f8656-5550-40d2-9f39-c58f57279489</wsa:MessageID>
<wsa:Action>http://provider.ws/TestServiceDelegate/callServiceRequest</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<ns2:callService xmlns:ns2="http://provider.ws/"/>
</soapenv:Body></soapenv:Envelope>
The body consists of a single line, and this makes the scenario a peculiar one, as well as raises a question is this is meant to work at all.
I can suggest two things:
You can attempt to parse your WSDL file with the SOAPUI application; it should show you how the SOAP envelope is supposed to look like
Use the Service Discovery feature in MobileFirst Studio that can generate the adapter for you with a ready SOAP envelope. Read more how to use this feature, here: http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.0.0/com.ibm.worklight.dev.doc/dev/c_using_service_discovery_wizard_to_explore_backend-services.html

Use of charter encoding with content type in JAX-RS 2.0 - Jersey

I am developing JAX-RS 2.0 client with Jersey implementation. REST API returns response with content type as 'application/json; UTF-8'
At client side, Jersey cannot recognize this content-type and throws error like
Unable to parse "Content-Type" header value: "application/json; UTF-8"
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "Content-Type" header value: "application/json; UTF-8"
at org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:318)
at org.glassfish.jersey.message.internal.InboundMessageContext.singleHeader(InboundMessageContext.java:313)
at org.glassfish.jersey.message.internal.InboundMessageContext.getMediaType(InboundMessageContext.java:427)
If content type is "application/json" same code could process the response. I tried to search over google and some posts say that such character encoding along with content type is supported in Jersey but I didn't find it working.
Following is code I am trying with.
Client clientSaml = ClientBuilder.newBuilder().sslContext(context)
.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method`enter code here` stub
return true;
}
}).build();
clientSaml.register(new SAMLAuthenticator(token));
clientSaml.register(new LoggingFilter());
WebTarget target = clientSaml
.target(URL_OF_API);
Response resp = target.request(MediaType.APPLICATION_JSON).get();
System.out.println(resp.getMediaType().toString());
Does anybody had this issue before and what could be possible solution of this ?? Does any other implementation of JAX-RS support it ?
You forgot charset=:
Content-Type: application/json; charset=UTF-8
See Section 14.17 Content-Type of HTTP 1.1.
I did workaround of this issue using ClientResponseFilter
Thanks to hint suggested in Jersey and #FormParam not working when charset is specified in the Content-Type

savon soap attributes

Am trying to query netsuite api for currencies. The following soap request works for me in SOAP UI client. But i am having a hard time trying to get the same working with ruby's savon gem version 0.9.7.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:messages_2012_2.platform.webservices.netsuite.com" xmlns:urn1="urn:core_2012_2.platform.webservices.netsuite.com">
<soapenv:Header>
<urn:passport>
<urn1:email>xxx#abc.com</urn1:email>
<urn1:password>xxx</urn1:password>
<urn1:account>xxx</urn1:account>
</urn:passport>
</soapenv:Header>
<soapenv:Body>
<urn:getAll>
<urn:record recordType="currency"/>
</urn:getAll>
</soapenv:Body>
</soapenv:Envelope>
Basically i am not able to set the attribute on the urn:record element. The following is not working:
response = client.request :urn, :get_all do
soap.body = { "urn:record" => { :attributes! => { "recordType" => "currency" } } }
end
Please advise.
As explained on http://savonrb.com the key in the attributes! hash has to match the XML tag. You want to write something like this:
response = client.request :urn, :get_all do
soap.body = {'urn:record'=>'',
:attributes!=>{'urn:record'=>{'recordType'=>'currency'}}
}
end
Please let us know whether this solves it for you.
Double-check the raw soap request. :get_all may need to be "getAll" to have savon take you literally; it may be changing it to GetAll
In new versioin of savon you can place :attributes in the local context for the operation tag:
#interaction_client.call(:retrieve_interaction, message: message_hash, :attributes => { 'attachmentInfo' => include_attachments.to_s })
In this case, the attachmentInfo attribute will be placed into the main operation tag linked with operation, in this example this would be the ns:RetrieveInteractionRequest tag.
Please note that the syntax does not contains the exclamation mark.