Access fields from an http response by parsing the response - messagebroker

I got an XML Response
<?xml version="1.0"?>
<List>
<type>MAILBOX</type>
<DOCS>
<DocId>39fece005f28qrn8000003r5</DocId>
<DocNo>123</DocNo>
</DOCS>
<DOCS>
<DocId>39fece005f28qrn8000003r6</DocId>
<DocNo>456</DocNo>
</DOCS>
</List>
I need to parse it so that I can use it and access DocId; what should be proper code to access docid?

You need to set up parsing on the HTTPRequest node, on the Response Message Parsing tab you select XMLNSC as the message domain, then on the output terminal you can use another Compute node and access the parts of the message as normal in ESQL, e.g.: InputBody.List.DOCS[1].DocId

Related

How can I put an XML mocked payload into a POST request payload sended by a WSO2 ESB send mediator?

I am absolutly new in WSO2 ESB and at this time I have to achive this first simple task but I really don't know from where start.
I have to perform an HTTP POST request towards an external web service. This request should contains a mocked XML document as payload (at this time the XML have to be merely mocked so I think that I have to "write" it somewhere or something like this).
So starting by this minimalistic official tutorial:
https://docs.wso2.com/display/ESB500/Sending+a+Simple+Message
I have done the following operation:
1) I have created a new ESB Solution Project.
2) On the "main" project named SampleServices (at this time I am using the same name of the tutorial) I have registered the endpoint to my external web service (New -> Endpoint).
3) Then on this project I have add a new RESP API (New -> REST API). Differently from the tutorial I have enable POST request instead of GET into the API Resource properties because I need to send a POST request containing a payload instead the tutorial GET request. This is my settings:
4) Then, as done in the tutorial, I have setted the send mediator and on this mediator I have setted the defined endpoint pointing at my external web service that have to handle the POST request and retrieve its payload.
Ok, now my problem is: how can I put a mocked XML document into the body of my POST request sended by my *send mediator**?
Reading this second tutorial:
https://docs.wso2.com/display/ESB500/Routing+Requests+Based+on+Message+Content
I know that I can pass the request payload from outside, for example in this second tutorial perform this CURL call that starts the ESB "process":
curl -v -X POST --data #request.json http://localhost:8280/healthcare/categories/surgery/reserve --header "Content-Type:application/json"
This do a call that pass a JSON as payload. In the previous example works fine but it is not good for me.
I have to mock the XML document payload inside my ESB API flow and not take from an external request performed by CURL because in a second implementationstep it will not be mocked but il will come from a previous step in the chain.
So I need a flow like this:
When my API is called it perform a POST request that send a mocked XML payload. Maybe it is have to be putted into the send mediator but I don't know...
How can I put this XML in the payload of the requeste sended by the send mediator? Where have I to define\write it?
Check this sample:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/services/users" name="ListUsersAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" url-mapping="/*">
<inSequence>
<payloadFactory media-type="json">
<format>{ "persons":[{ "person": { "Id":"1", "givenName":"ajith", "lastName":"vitharana", "age":"25", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email", "value":"ajith#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile",
"value":"111111111" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] }}, {"person":{ "Id":"2", "givenName":"shammi", "lastName":"jagasingha", "age":"30", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email",
"value":"shammi#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile", "value":"2222222222" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] } }] }</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>

SoapUI response parsing for property transfer

I have a soap response containing transaction ID (TranId).
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m0="http://schemas.blablabla.com/two/1.0/filter.xsd" xmlns:m="http://schemas.blablabla.com/two/1.0/filter.wsdl">
<SOAP-ENV:Body>
<m:AcctDebitRp xmlns:m="http://schemas.blablabla.com/two/1.0/filter.xsd">
<Response Response="1" TranId="**30538801**" Ver="14.3" Product="filter">
<m0:ApprovalCode>557885</m0:ApprovalCode>
</Response>
</m:AcctDebitRp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How can I retrieve transaction id value ?
I am using the below code in SoapUI property transfer step to retrieve the value of ApprovalCode:
declare namespace ns1='http://schemas.blablabla.com/two/1.0/filter.xsd';
//ns1:ApprovalCode
Is it possible to get the TranId value using XQuery in property transfer step or using groovy script step?
You can query for attributes using an #attributename child step. In the example you provided, the <Response/> element has no namespace attached, thus the query for the attribute is a simple
//*:Response/#TranId
If you only want the attribute value, consider applying the data(...) function:
data(//*:Response/#TranId)

XSD validation fails with UndeclaredPrefix when using AxiomSoapMessageFactory in Spring WS

I'm building a contract-first SOAP web service with spring-ws 2.2.3. My XML Schema uses extensions, leading to xsi:type= attributes in the XML requests. Since some respones can be very large (30MB), I'm using a AxiomSoapMessageFactory instead of the default SaajSoapMessageFactory, as suggested in the Spring WS docs. I validate incoming requests with a PayloadValidatingInterceptor:
PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
interceptor.setSchema(new ClassPathResource("format-service.xsd"));
interceptor.setValidateRequest(true);
interceptor.setValidateResponse(false);
My problem is that I get spurious validation errors, depending on where in the XML the namespace is declared: if it's declared in the payload, then everything works fine:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<sch:formatRequest xmlns:sch="http://example.com/springws/extension/schema">
<sch:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="sch:currencyType">
<sch:amount>1000</sch:amount>
<sch:currency>EUR</sch:currency>
</sch:value>
</sch:formatRequest>
</soapenv:Body>
</soapenv:Envelope>
But as soon as I move the sch namespace declaration up to the Envelope:
<soapenv:Envelope xmlns:sch="http://example.com/springws/extension/schema" ...>
validation fails and I receive a SOAP Fault:
<faultcode>soapenv:Client</faultcode>
<faultstring xml:lang="en">Validation error</faultstring>
<detail>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-elt.4.1: The value 'sch:currencyType' of attribute 'http://www.w3.org/2001/XMLSchema-instance,type' of element 'sch:value' is not a valid QName.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.2: The type definition cannot be abstract for element sch:value.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-attribute.3: The value 'sch:currencyType' of attribute 'xsi:type' on element 'sch:value' is not valid with respect to its type, 'QName'.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-complex-type.2.1: Element 'sch:value' must have no character or element information item [children], because the type's content type is empty.</spring-ws:ValidationError>
</detail>
It appears like a bug in the AxiomSoapMessageFactory / Axiom implementation to me (namespace context is lost), as both requests validate fine when using the SaajSoapMessageFactory. Note that the validation only fails on the xsi:type= attribute. The same namespace is recognized correctly for elements.
I cannot use SaajSoapMessageFactory due to high memory consumption for large responses. I found similar problems described in the Spring forum and on SO, but no solution. Thanks for help!
The reason is that Spring-WS uses OMContainer#getXMLStreamReader(). Instead it should use OMContainer#getXMLStreamReader(boolean, OMXMLStreamReaderConfiguration) and set the preserveNamespaceContext property to true in the OMXMLStreamReaderConfiguration object.
You should file a bug for Spring-WS, or even better, fix the issue and submit a pull request.

MSXML: XMLHTTP doesn't support charset from header

I'm using MSXML2_TLB.pas generated from the Microsoft XML type library to call a pretty simple web-service, so I don't need the full XML wrapping and just do this:
var
r:XMLHTTP;
begin
r:=CoXMLHTTP.Create;
r.open('POST',WebServiceURL,false,'','');
r.setRequestHeader('Content-Type','application/xml');
r.send('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" '+
'xmlns:ns="http://somebigcorporation.com/api/ws1/">'+
'<soapenv:Body>'+
//snip: irrelevant to the question
'</soapenv:Body></soapenv:Envelope>');
if r.status<>200 then raise Exception.Create(r.statusText);
Result:=(r.responseXML as DOMDocument).documentElement.firstChild.firstChild.selectSingleNode('importantData');
end;
The webservice responds nicely with status 200 and Content-Type: text/xml; charset=iso-8859-1.
In some cases, documentElement is nil (and the above code throws an access violation). Apparently responseXML exists, but only to offer a parseError object (it says so in the docs), and parseError.reason in these cases is An invalid character was found in text content..
Why is the parser not taking the 'charset' value from the response header? Is there a way to tell the XMLHTTP instance to use the charset value from the response header?
Update: I don't know if it's important, but the response also doesn't start with <?xml and even if it did I have no way to request/modify it so it would have an encoding="iso-8859-1" attribute.
I think you need to set the charset in the request so the result is correct.
r.setRequestHeader('Content-Type', 'application/xml; charset=ISO-8859-1');

Rails not getting params from HTTP request

I'm trying to POST the following data to a Rails server (running on WebRick) from Android.
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<data>
<email>email.test#name.com</email>
<password>APassw0rd</password>
<remember_me>1</remember_me>
</data>
Now, the funny thing is that these data never show up in the params field in the controller.
Webrick does not output any parsing error. (And I guess it would post an error if it received a POST with no data attached:
Started POST "/users/sign_in.xml" for 192.168.1.94 at 2012-12-14 17:33:20 +0100
Processing by Users::SessionController#create as XML
Completed 500 Internal Server Error in 22643ms
I also found no trace of the data in the request.env variable. Actually, I see no HTTP_BODY in the dump fields. How can one see the raw body of the request? Would webrick really not complain if it received a POST with no attached data?
request.env would show the data as an IO object so you wouldn't be able to see your xml directly.
request.raw_post should return the raw data.
For rails to try and parse your xml into the params hash directly you need to set the content type of the request to application/xml. The 'processing as xml' stuff means that rails will try to render an xml response and doesn't necessarily have any bearing on the format of the posted data

Resources