SOAP Fault unexpected element but looks same - spring-boot

I am receiving this error. I have seen this answered several time but in those quesitons there was a wrogn name or case issue. This they look the same.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">unexpected element (uri:"http://service.xxx.com/provider/aaa/bbb/2015/", local:"retrieveAccountRequest"). Expected elements are <{http://service.xxx.com/provider/aaa/bbb/2015/}tns:retrieveAccountRequest></faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I did not notice the "tns:" on the expected elements. It is always the stupid, careless stuff that gets you.

Related

How do you properly unmarshall an SOAP string with XML namespaces?

I'm having a hard time figuring out how to correctly and safely unmarshall a SOAP response with the following shape:
<xml>
<soap-env:Envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header></soap-env:Header>
<soap-env:Body>
<n0:ZcustomerMasterInfoResponse
xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<EOutput>
...Additional tags
</EOutput>
<n0:ZcustomerMasterInfoResponse/>
</soap-env:Body />
</soap:Envelop />
</xml>
This would be trivial with basic tags but there's quite a few namespaces such as soap-env, n0 etc. that are making it more complex to parse.

Execution of xpath failed in Mulesoft

My Mulesoft process is making a call to SuccessFactors API. The /LOGIN call results in a response like this.
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<loginResponse xmlns="urn:sfobject.sfapi.successfactors.com" xmlns:ns2="urn:fault.sfapi.successfactors.com">
<result>
<sessionId>9A95*******A2631B8E820894CA.ps8bsfapi52t</sessionId>
<msUntilPwdExpiration>9223372036854775807</msUntilPwdExpiration>
</result>
</loginResponse>
</S:Body>
</S:Envelope>
I've the following name spaces declared in my namespace manager
<mulexml:namespace-manager>
<mulexml:namespace prefix="S" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<mulexml:namespace prefix="ns2" uri="urn:fault.sfapi.successfactors.com"/>
<mulexml:namespace prefix="" uri="urn:sfobject.sfapi.successfactors.com"/>
</mulexml:namespace-manager>
I want to read the sessionId into a mule session variable.
<set-session-variable variableName="SESSION" value="#[xpath('//S:Envelope/S:Body/loginResponse/result/sessionId').text]" doc:name="Get Session from Login"/>
But, upon execution I end up in this
<faultstring>Execution of the expression "xpath('//S:Envelope/S:Body/loginResponse/result/sessionId').text" failed. (org.mule.api.expression.ExpressionRuntimeException).</faultstring>
The XPath checks out well on any other tool but for Mulesoft.
Use XPATH with * as namespace, so you dont need to bother about namespace.
#[xpath('//*:Envelope/*:Body/*:loginResponse/*:result/*:sessionId').text]
xpath is deprecated new version of mule.
Update:
#[xpath3('//*:Envelope/*:Body/*:loginResponse/*:result/*:sessionId')]
Hope this helps.

Soap Fault Details custom exception

In the process of moving to Spring WS and using JAXB from wsdl to generate the objects used in the Soap message. I am having an issue trying to get the Custom Exception into the details field of the Soap Fault message. The following is how the existing fault message is returned (FooException embedded in detail).
<env:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Service specific exception: com.test.FooException: Invalid authentication credentials. Please try again.</faultstring>
<detail>
<n1:FooException xsi:type="n1:FooException" xmlns:n1="java:com.test">
<errorCode xsi:type="xsd:int">101</errorCode>
<errorReason xsi:type="xsd:string">InvalidUserCredentials:Invalid authentication credentials. Please try again</errorReason>
</n1:FooException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
I have setup a customer exceptionResolver bean identifier in the spring config xml file.
<bean id="exceptionResolver" class="com.test.FacadeExceptionHandler">
<property name="order" value="1"></property>
<property name="defaultFault" value="SERVER"/>
<property name="exceptionMappings">
<value> com.test.FooException=SERVER,FaultMsg </value>
</property>
</bean>
I created the FacadeExceptionHandler and it is getting called, but I cannot figure out how to get the FooException into the details portion of the fault message.
Any help would be appreciated!!!
Thanks in advance for your help!
I think you almost get it all, in your FacadeExceptionHandler you must override the customizeFault method (doc) and then add the detail for the fault (you have your Exception as a parameter there).
All this custom detail handling for Soap Fault messages is explained in detail in this entry: http://www.stevideter.com/2009/02/18/of-exceptionresolvers-and-xmlbeans/
You cannot return to SOAP client fault with such depth of nested elements in <detail> element cause in Spring WS SoapFault has list of SoapFaultDetail which has list of SoapFaultDetailElement but SoapFaultDetailElement is just detail message in String. So in Spring WS max depth of SOAP Fault details is one.
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Сообщение не соответствуют схеме сервиса СМЭВ.</faultstring>
<detail>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.a: Invalid content was found starting with element 'ns:SenderProvidedRequestData1'. One of '{"urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1":SenderProvidedRequestData}' is expected.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.3: Element 'ns:CallerInformationSystemSignature' cannot have character [children], because the type's content type is element-only.</InvalidContent>
<InvalidContent xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1">cvc-complex-type.2.4.b: The content of element 'ns:CallerInformationSystemSignature' is not complete. One of '{WC["http://www.w3.org/2000/09/xmldsig#"]}' is expected.</InvalidContent>
</detail>
</SOAP-ENV:Fault>

Validate XML against 2 XSD

I'm trying to parse and validate a SOAP request with SAX. Two XSD are necessary, one for SOAP envelope (http://schemas.xmlsoap.org/soap/envelope/) and the one I defined. I cannot find a way to properly validate the request against these two XSD.
Here's the code I use to parse the request and validate it against soapenv.xsd. It works fine. If I specify my XSD instead, the validation fails with "Cannot find the declaration of element 'soapenv:Envelope'".
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
SAXParser saxParser = factory.newSAXParser();
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/soapenv.xsd"));
InputSource is = new InputSource(MyClass.class.getResourceAsStream("/xml/request.xml"));
XMLReader reader = saxParser.getXMLReader();
reader.setContentHandler(new MyHandler());
reader.setErrorHandler(new MyErrorHandler());
reader.parse(is);
How can I specify a second XSD?
Is there a better way to parse and validate SOAP requests?
EDIT
As proposed, I created thirdpty.xsd that imports my two XSDs.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="thirdparty:general"
xmlns="thirdparty:general"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\soapenv.xsd"
namespace="http://schemas.xmlsoap.org/soap/envelope/"/>
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\Presence.xsd"
namespace="thirdparty:presence"/>
</xs:schema>
I specify this new XSD for the validation:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/thidpty.xsd"));
But still, only the SOAP envelope XSD is used for validation. If a modify one element from my other XSD, the validation does not detect it.
Here is the xml I am trying to validate
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="thirdparty:presence">
<soapenv:Header/>
<soapenv:Body>
<urn:getPresenceQuery>
<urn:origAccount uri="test#origin.com"/>
<urn:destAccount uri="test#destination.com"/>
</urn:getPresenceQuery>
</soapenv:Body>
</soapenv:Envelope>
Other ideas ?
Write a driver schema document which imports the other two; validate against the driver.

Xpath Post Processor : extract node content from a SOAP response

I have a soap response of this form
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:Responseto xmlns:ns2="http://xyz.company.com/">
<return>
<objectContent xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">/path/to/file.txt</objectContent>
<objectType>FILEPATH</objectType>
<rid>111</rid>
<sid>2</sid>
</return>
</ns2:Responseto>
</S:Body>
</S:Envelope>
I wish to extract the object content in jmeter in order to feed to an xpath assertion.
Can anyone suggest how to do this?
I tried //return/objectType but then the DebugSampler shows me that the value of my variable is blank.
Put you XPath Extractor as a child of the Request that has the response you mention.
Configure the extractor like this:
"Main Sample" Only
"Use Namespaces" checked
"Ignore Whitespaces" checked
"Return entire XPath fragment instead of text content" Unchecked
"XPath query" : //return/objectType
I tested it it works.

Resources