How to retrieve SOAP response header in a SOAPFaultException in Apache CXF - soap

I have a trouble in Apache CXF where some code throws SOAPFaultException.
My original SOAP response is as following :
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope ...>
<soap:Header>
<awsse:Session TransactionStatusCode="InSeries">
<awsse:SessionId>012GBF5W3H</awsse:SessionId>
<awsse:SequenceNumber>1</awsse:SequenceNumber>
<awsse:SecurityToken>3CGFFDO499VDB7WTRT37R6HPV</awsse:SecurityToken>
</awsse:Session>
</soap:Header>
<soap:Body>
<soap:Fault xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>soap:Client</faultcode>
<faultstring>SOME_FAULT_STRING</faultstring>
<faultactor>SOME_FAULT_FACTOR</faultactor>
</soap:Fault>
</soap:Body>
</soap:Envelope>
I receive later a SOAPFaultException with information contains only soap:Body/soap:Fault. However, I need information from soap:Header section for further processing.
How can I pass these Header information to SOAPFaultException?

Related

SOAP Object reference not set to an instance of an object

I'm attempting to run a search for a ticket on ChangeGear 5.0. Their API utilizes SOAP requests, and when I run a request to search I get the error "Object reference not set to an instance of an object". I've looked through existing topics concerning the same issue (there are a lot of them), and I've tried all of them with no luck. Non-required parameters are included as empty tags instead of omitted entirely, I've tried capitalizing the names of the parameters, and I've made sure the request is formatted appropriately according to the WSDL.
The provided ChangeGear 5.0 documentation specifies to structure requests like so:
POST /cgweb/cgwebservices/cgwebservices.asmx HTTP/1.1
Host: ...
Content-Type: application/soap+xml; charset=utf-8
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<Search xmlns="http://www.sunviewsoftware.com/CGWebServices/">
<sessionId>string</sessionId>
<entityType>string</entityType>
<criteria>string</criteria>
<retrieveRelated>boolean</retrieveRelated>
<entityTemplate>string</entityTemplate>
</Search>
</soap12:Body>
</soap12:Envelope>
This is the request I'm POSTing with the specified headers:
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<Search xmlns="http://www.sunviewsoftware.com/CGWebServices/">
<sessionId></sessionId>
<entityType></entityType>
<criteria></criteria>
<retrieveRelated>true</retrieveRelated>
<entityTemplate></entityTemplate>
</Search>
</soap12:Body>
</soap12:Envelope>
The only parameter I've set is retrieveRelated because as specified by the WSDL it is the only required parameter, but I've also tried setting all the string parameters to arbitrary non-null values and received the same result. I'm sure the API is functional because when I use the login operation it returns successfully:
POST /cgweb/cgwebservices/cgwebservices.asmx HTTP/1.1
Host: ...
Content-Type: application/soap+xml; charset=utf-8
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<Login xmlns="http://www.sunviewsoftware.com/CGWebServices/">
<userName>...</userName>
<password>...</password>
</Login>
</soap12:Body>
</soap12:Envelope>
Result:
200 OK
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<LoginResponse xmlns="http://www.sunviewsoftware.com/CGWebServices/">
<LoginResult>...</LoginResult>
</LoginResponse>
</soap:Body>
</soap:Envelope>
I am using the same session I used for the login operation. Is there anything else I can try besides including empty tags for omitted parameters or capitalizing their names? The full error is:
500 Internal Server Error
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Object reference not set to an instance of an object.</soap:Text>
</soap:Reason>
<soap:Node>.../cgweb/cgwebservices/cgwebservices.asmx</soap:Node>
<detail>
<Error xmlns=".../cgweb/cgwebservices/cgwebservices.asmx">
<ErrorNumber>0</ErrorNumber>
<ErrorMessage/>
<ErrorCode>L_REJECT_CHANGES_FAILED</ErrorCode>
</Error>
<Error xmlns=".../cgweb/cgwebservices/cgwebservices.asmx">
<ErrorNumber>0</ErrorNumber>
<ErrorMessage>Object reference not set to an instance of an object.</ErrorMessage>
<ErrorCode>Object reference not set to an instance of an object.</ErrorCode>
</Error>
<Error xmlns=".../cgweb/cgwebservices/cgwebservices.asmx">
<ErrorNumber>0</ErrorNumber>
<ErrorMessage>Object reference not set to an instance of an object.</ErrorMessage>
<ErrorCode/>
</Error>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
The problem was that the server wasn't adhering to the WSDL. The entityTemplate parameter was required, and without it the server returns the "Object reference not set to an instance of an object" error. When I initially tested the parameters with dummy values, out of coincidence I had accidentally forgot to set this one -- the only one that strayed from the WSDL specification.

Get the soap request skeleton

I am using the soapUI core (classes) to invoke operation for the given WSDL.
I am trying to get the soap request skeleton of a given operation.
Is there any method in WsdlOperation, WsdlRequest that return the skeleton of the soap request. for example:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
</soap:Header>
<soap:Body>
<soap:Fault>
</soap:Fault>
</soap:Body>
Thanks.

EWS request fails because not Internet

I am calling EWS service on internal network which has not access to Internet.
I can open EWS url with browser and verify that it is up an running.
But when I try to send the SOAP request.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2007_SP1" />
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="calendar" />
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
It fails with error ENOTFOUD. I am assuming that it can not connect to given address in the SOAP xml for schema definitions.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
How to deal with this when there is no internet connection.
I am sending request from meteor.js app using lather.js library.
The stuff that looks like URL:s, prefixed with xmlns, are just name spaces and shall not be called. A bit like namespaces in a java program (for example namespace com.sun.something) is not an url you can call.
You should just do a http POST and send the entire xml file to the soap server, which can be an internal ip number that is not on the internet.

How do I mangle namespace generation in SOAP::Lite?

Scenario:
The client is a Perl script using SOAP::Lite.
The server is a Java based application using Spring and CXF.
My client is producing based on the WSDL the following SOAP request:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<createFolder xmlns="http://xyz.com/">
<parentId xsi:type="xsd:string">1</parentId>
<folderName xsi:type="xsd:string">Test</folderName>
</createFolder>
</soap:Body>
</soap:Envelope>
This request will fail against CXF. After several investigations I found out that the following manually produced request will work:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xyz="http://xyz.com/">
<soap:Body>
<xyz:createFolder>
<parentId xsi:type="xsd:string">1</parentId>
<folderName xsi:type="xsd:string">Test</folderName>
</xyz:createFolder>
</soap:Body>
</soap:Envelope>
The difference is the namespace definition for the element createFolder.
My question is: How can I configure SOAPLite to create the working SOAP request?
Or vice versa: How can CXF be configured to accept the SOAP::Lite request style?
Look under ns. If gives a similarly qualified name for root element of the fragment
Using the following:
SOAP::Lite->new->proxy( 'http://somewhere.com' )
->ns( 'http://xyz.com/', 'xyz' )->createFolder(
SOAP::Data->new( name => 'parentId', value => 1, type => 'xsd:string' )
, SOAP::Data->new( name => 'folderName', value => 'Test' )
);
I got the following:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xyz="http://xyz.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
>
<soap:Body>
<xyz:createFolder>
<parentId xsi:type="xsd:string">1</parentId>
<folderName xsi:type="xsd:string">Test</folderName>
</xyz:createFolder>
</soap:Body>
</soap:Envelope>
And I think that's what you want.

Auth in sharepoint wsdl

I used soapUI tool for fetch soap request from my dummy wsdl server
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
</soap:Body>
</soap:Envelope>
and take response. But when I try to take request from my real server I cant auth. In soap envelope I added header
<soap:Header>
<AUTHHEADER>
<USERNAME>Administrator</USERNAME>
<PASSWORD>Password</PASSWORD>
</AUTHHEADER>
</soap:Header>
but something wrong. Login and pass is right, I checked.
UPD1
I send query like this
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:AUTHHEADER>
<soap:USERNAME>Administrator</soap:USERNAME>
<soap:PASSWORD>Password</soap:PASSWORD>
</soap:AUTHHEADER>
<soap:Body>
<GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
</soap:Body>
</soap:Envelope>
and I have
<soap:Envelope 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:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Server was unable to read request. ---> Request format is invalid: Missing required soap:Body element.</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
from real server.
Try to change your query like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns:ns0="http://schemas.microsoft.com/sharepoint/soap/">
<ns0:AUTHHEADER>
<ns0:USERNAME>Administrator</ns0:USERNAME>
<ns0:PASSWORD>Password</ns0:PASSWORD>
</ns0:AUTHHEADER>
</soap:Header>
<soap:Body>
<GetListCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />
</soap:Body>
</soap:Envelope>
EDIT1: repair example to add another ns to authheader. Be honest: I don't know, if there is defined an authheader elements in ns of http://schemas.microsoft.com/sharepoint/soap, but I pretend it, because it can be different for every WSDL interface. I know, that there is WSSE standard, but it is coded in XML request differently.