SSRS - passing complex parameters to a webservice - web-services

I am trying to get data from a webservice to put in a SSRS report.
Here is a dataset that works with a simple string parameter (The parameter is set in dataset properties):
<Query xmlns="http://tempuri.org/">
<Method Name="ValidateUserWSToken" Namespace="http://tempuri.org/" />
<SoapAction>http://tempuri.org/WSTokenService/ValidateUserWSToken</SoapAction>
</Query>
Here is a similar method that expects a complextype for it's parameter
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/"/>
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
</Query>
Putting the parameter in the dataset properties as
<UserName>username</UserName><Password>password</Password>
gives the error "There was an error trying to deserialize parameter http://tempuri.org/:request. The InnerException message was 'Error in line 5 position 20. Expected state 'Element'.. Encountered "text" with name '', namespace ''.'.". I don't think setting this in dataset properties will work.
I have tried variations on the following to try to put the parameter in the query text
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/" />
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
<Parameters>
<Parameter Name="request" type="xml">
<DefaultValue xmlns:a="some namespace">
<a:Password>password</a:Password>
<a:UserName>username</a:UserName>
</DefaultValue>
</Parameter>
</Parameters>
</Query>
but these all fail with a 500 error - "Object reference not set to an instance of an object.", presumably because the webservice is not finding the parameter or finding it is null.
Here is the XML that SoapUI produces (and works)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:civ="some namespace">
<soapenv:Header/>
<soapenv:Body>
<tem:GetUserWSToken>
<!--Optional:-->
<tem:request>
<civ:Password>password</civ:Password>
<civ:UserName>username</civ:UserName>
</tem:request>
</tem:GetUserWSToken>
</soapenv:Body>
</soapenv:Envelope>
Can this be converted into something I can use in SSRS query text?

This works:
<Query>
<Method Name="GetUserWSToken" Namespace="http://tempuri.org/">
<Parameters>
<Parameter Name="request" Type="XML" xmlns="some namespace">
<DefaultValue>
<Password>password</Password>
<UserName>username</UserName>
</DefaultValue>
</Parameter>
</Parameters>
</Method>
<SoapAction>http://tempuri.org/WSTokenService/GetUserWSToken</SoapAction>
<ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>
and this is what it is converted to:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUserWSToken xmlns="http://tempuri.org/">
<request><Password xmlns="some namespace">Password123</Password><UserName xmlns="some namespace">FifeIntegrationUser</UserName></request>
</GetUserWSToken>
</soap:Body>
</soap:Envelope>

Related

Validation String XSLT WSO2

I'm newbie about validation on programming. Like Checking string and checking field input empty or not. Maybe anyone in here can share me about simple sample validation rule about string and checking field to me with XSLT. Thanks
First of all, XSLT is for XML transformations and if you want to do schema validations you should be looking at XSD validations. Having said that below is how you can use XSLT to validate a message and generate a payload.
Let's say you have a Payload like the below.
<Request>
<messages>
<message>
<id>123</id>
<name>Not Empty</name>
</message>
<message>
<id>234</id>
<name></name>
</message>
</messages>
</Request>
In the above payload, you want to check each message and check whether the name is empty or not. Inorder to validate this you can use XSLT. First create a XSLT as a LocalEntry in the local-entries directory. You can use the following content. (You can create your XSLT in the registry as well)
<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="LOCAL_XSLT_NullCheck" xmlns="http://ws.apache.org/ns/synapse">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<Response>
<!-- Iterating through message elements -->
<xsl:for-each select="//messages/message">
<message>
<messageID><xsl:value-of select="id/text()"/></messageID>
<xsl:choose>
<!-- Check if name is empty -->
<xsl:when test="boolean(name/text())">
<isEmpty>false</isEmpty>
</xsl:when>
<xsl:otherwise>
<isEmpty>true</isEmpty>
</xsl:otherwise>
</xsl:choose>
</message>
</xsl:for-each>
</Response>
</xsl:template>
</xsl:stylesheet>
</localEntry>
Next create a API to consume your request and to validate the payload and then to generate the response.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/xslt" name="TestAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<log level="full">
<property name="Message" value="Incoming Message"/>
</log>
<xslt key="LOCAL_XSLT_NullCheck"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Now once you invoke the API with the aforementioned message. You should see the following response.
<Response xmlns="http://ws.apache.org/ns/synapse">
<message>
<messageID>123</messageID>
<isEmpty>false</isEmpty>
</message>
<message>
<messageID>234</messageID>
<isEmpty>true</isEmpty>
</message>
</Response>
You ca read more on XSLT mediator from here. You can also consider using FastXSLT Mediator as well based on your requirement. Read more on XSLT from here.

postman: namespace on the "MasterDataReplReqMsg" element, is not a valid SOAP version

I am using postman to post a SOAP message to a target URL https://testacig.ariba.com/cxf/receiveERPMD. below is the payload
<?xml version="1.0"?>
<n0:MasterDataReplReqMsg xmlns:prx="urn:sap.com:proxy:DD2:/1SAI/TASD374B56E2305E7E70622:754" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:n0="http://sap.com/xi/ARBCIG1">
<Header>
<Parameters>
<Parameter name="UUID">
<value>005056893BDD1EDB88E738052AFE58D8</value>
</Parameter>
<Parameter name="realm">
<value>relamname</value>
</Parameter>
<Parameter name="fullload">
<value>true</value>
</Parameter>
<Parameter name="event">
<value>Import External System Master Data</value>
</Parameter>
<Parameter name="clienttype">
<value>DirectConnect</value>
</Parameter>
<Parameter name="clientversion">
<value>Addon- Direct Connectivity</value>
</Parameter>
<Parameter name="clientinfo">
<value>10.242.99.33-nbaps492</value>
</Parameter>
<Parameter name="operation">
<Parameter name="systemId">
<value>DECLNT111</value>
</Parameter>
<Parameter name="Solution">
<Parameter name="SystemId">
<value>DECLNT111</value>
</Parameter>
</Parameters>
<AttachmentFolder fileName="processing20201110104659_1.zip" contentType="application/zip" contentLength="" contentID="FOL33000000000004EXT39000000000138">
<Content xmlns="">UEsDBBQAAAAIAN5ValFIb/vgcAAAAIgAAAAOAAAASXRlbU1hc3Rlci5jc3YLDXHTteDyTSxJLcpMzPErzU1KLdKBcUMqC1LhHPei/NICHafE4tTQvMyS/DTf1MTi0qJUHf+ilNQikJBOcmlxSX6uW2ZqTgqXkrOHroGhroGRko6Sm2tQCJDyMTAwBlIBzq5AEoggysMSc0pTlbgAUEsDBBQAAAAIAN5ValHkI36wfAAAAJEAAAAdAAAASXRlbU1hc3RlckRlc2NyaXB0aW9uTGFuZy5jc3ZVjTsOwjAQBXufwnJtSwkVNUkgBaTh06/xyrK0WUfrWFwfU9I9aWb0no+zO6ob7CgJaKmrR7EjlrekbU+Z7RU4VoiozDC7rnfdwVhzAY9UdtgIRZ</Content>
</AttachmentFolder>
</Header>
</n0:MasterDataReplReqMsg>
when do POST request I get below error message and status code as 500
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:VersionMismatch</faultcode>
<faultstring>"http://sap.com/xi/ARBCIG1", the namespace on the "MasterDataReplReqMsg" element, is not a valid SOAP version.</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
what could be the reason ?
You will need to wrap your payload in a SOAP envelope. Something like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<n0:MasterDataReplReqMsg ...>
...
</n0:MasterDataReplReqMsg>
</soap:Body>
</soap:Envelope>

Building SOAP request from WSDL

I need to execute a SOAP request to an external server. I have never worked with SOAP before, but I know the basics of REST.
I've been given this following WSDL file and this example query:
<Messages>
<Version Ds_Version="0.0">
<Message>
<Detail>
<Ds_MerchantCode>999008881</Ds_MerchantCode>
<Ds_Terminal>1</Ds_Terminal>
<Ds_Order>5799L</Ds_Order>
<Ds_TransactionType>3</Ds_TransactionType>
</Detail>
</Message>
</Version>
<Signature>UfECD0KD9Wwo1iqY6PYZoJxw8KwMUz8m18bgLyH3BCI=</Signature>
<SignatureVersion>HMAC_SHA256_V1</SignatureVersion>
</Messages>
I'm using Postman in order to test the API. Following some instructions I found on the internet, I added a Content-Type HTTP header with value text/xml and the SOAPAction HTTP header with value consultaOperaciones as found in the WSDL file.
I've set this body:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://webservices.apl02.redsys.es">
<m:consultaOperacionesRequest>
<Messages>
<Version Ds_Version="0.0">
<Message>
<Transaction>
<Ds_MerchantCode>999008881</Ds_MerchantCode>
<Ds_Terminal>1</Ds_Terminal>
<Ds_Order>5799L</Ds_Order>
<Ds_TransactionType>3</Ds_TransactionType>
</Transaction>
</Message>
</Version>
<Signature>1KoxTgTakbTprzJ2N/e9JJ8yw/C3QzeNafbUMCNGSFM=</Signature>
<SignatureVersion>HMAC_SHA256_V1</SignatureVersion>
</Messages>
</m:consultaOperacionesRequest>
</soap:Body>
</soap:Envelope>
However, when I send the request I receive the following error message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode>Server</faultcode>
<faultstring>Internal Error</faultstring>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
It's a generic SOAP error message, therefore I think that the problem has to be related to the codification instead of the external service.
Thanks in advance.
In the WSDL file you will see that the XML should be sent as a string:
<element name="consultaOperaciones">
<complexType>
<sequence>
<element name="cadenaXML" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</element>
Hence the XML sent should be:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.apl02.redsys.es">
<soapenv:Header/>
<soapenv:Body>
<web:consultaOperaciones>
<cadenaXML><![CDATA[
<Messages>
<Version Ds_Version="0.0">
<Message>
<Detail>
<Ds_MerchantCode>999008881</Ds_MerchantCode>
<Ds_Terminal>1</Ds_Terminal>
<Ds_Order>5799L</Ds_Order>
<Ds_TransactionType>3</Ds_TransactionType>
</Detail>
</Message>
</Version>
<Signature>UfECD0KD9Wwo1iqY6PYZoJxw8KwMUz8m18bgLyH3BCI=</Signature>
<SignatureVersion>HMAC_SHA256_V1</SignatureVersion>
</Messages>
]]>
</cadenaXML>
</web:consultaOperaciones>
</soapenv:Body>
</soapenv:Envelope>
Note that we are using CDATA because as mentioned the XML message should be sent as a string based on the WSDL. I have tried running it and got the response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<p259:consultaOperacionesResponse xmlns:p259="http://webservices.apl02.redsys.es">
<consultaOperacionesReturn><![CDATA[<Messages><Version Ds_Version="0.0"><Message><ErrorMsg><Ds_ErrorCode>XML0023</Ds_ErrorCode></ErrorMsg></Message></Version></Messages>]]></consultaOperacionesReturn>
</p259:consultaOperacionesResponse>
</soapenv:Body>
</soapenv:Envelope>
This means that your message is being parsed now because there are no server errors and a consultaOperacionesResponse is being sent which looks legit. The error seems to be related to the data being sent but in general the API is working fine as expected.

Apache CXF:The message has expired

Environment :
Apache CXF 2.7.8
Jboss EAP 6
SoapUI for testing client Side
I tried to implement for simple authentication i.e with password simple text type, it is working but when i tried to implement for password digest type ,then giving me exception:
unwinding now: org.apache.cxf.binding.soap.SoapFault: The message has
expired org.apache.ws.security.WSSecurityException: The message has
expired
I am giving new nonce value for each request and time within five min diff
WSS4JInInterceptor Bean class defination:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="orderProcess" implementor="demo.order.OrderProcessImpl" address="/OrderProcess" >
<jaxws:inInterceptors>
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordDigest"/>
<entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="myPasswordCallback" class="service.ServerPasswordCallback" />
</beans>
Client xml request Code:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ord="http://order.demo/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>joe</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">PE7F51/oyWFVMsiZURuUwjoZVPY=</wsse:Password>
<!--<wsu:Created>2013-12-17T13:12:00.429Z</wsu:Created>-->
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">efPSkfHXTM6NFDDD1CJHsw==</wsse:Nonce>
<wsu:Created>2013-12-23T12:17:15Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ord:processOrder>
<!--Optional:-->
<arg0>
<!--Optional:-->
<customerID>234</customerID>
<!--Optional:-->
<itemID>0908923</itemID>
<price>23423</price>
<qty>1000</qty>
</arg0>
</ord:processOrder>
</soapenv:Body>
</soapenv:Envelope>
When i tried to call the service i am getting exception as
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">ns1:MessageExpired</faultcode>
<faultstring>The message has expired</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Can any one tell me where i am making mistake?
I suspect this is a bug in earlier version of wss4j. If you are parsing the date using SimpleDateFormat, you might want to set the time zone to UTC (Zulu time).
sdf.setTimeZone("UTC");
This however has been fixed in 2.0-beta.
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.wss4j/wss4j-ws-security-dom/2.0-beta/org/apache/wss4j/dom/message/token/UsernameToken.java#226
Edit: This is not a bug in wss4j. The specification states that the time zone must be in UTC.

SharePoint Web Services Team Discussion and Replies

I am trying to get a discussion with all it's replies from the sharepoint web services but only seem to be able to get the root message and not any of the replies. Below is the soap XML. What am I missing?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
<soapenv:Header/>
<soapenv:Body>
<soap:GetListItems>
<!--Optional:-->
<soap:listName>Team Discussion</soap:listName>
<soap:viewFields>
<ViewFields>
<FieldRef Name='Title'/>
<FieldRef Name='ItemChildCount'/>
<FieldRef Name='Body'/>
</ViewFields>
</soap:viewFields>
<soap:queryOptions>
<QueryOptions>
<Folder>
"http://Lists/Team Discussion/Bite Me"
</Folder>
</QueryOptions>
</soap:queryOptions>
</soap:GetListItems>
</soapenv:Body>
</soapenv:Envelope>
The reply is:
<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>
<GetListItemsResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<GetListItemsResult>
<listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<rs:data ItemCount="2">
<z:row ows_Title="Hello" ows_ItemChildCount="3;#1" ows_Body="<div class="ExternalClass7B4989B3DC264716AD81B9CE55FD38FA"><p>​The text of the message</p></div>" ows_MetaInfo="3;#" ows__ModerationStatus="0" ows__Level="1" ows_ID="3" ows_UniqueId="3;#{6AF6D7DA-0D87-45EC-B002-AA0D153B6286}" ows_owshiddenversion="1" ows_FSObjType="3;#1" ows_Created="2012-01-11 12:21:26" ows_PermMask="0x7fffffffffffffff" ows_Modified="2012-01-11 12:21:26" ows_FileRef="3;#Lists/Team Discussion/Hello"/>
<z:row ows_Title="Bite Me" ows_ItemChildCount="1;#1" ows_Body="<div class="ExternalClass76A3DB4368714038B6B75DB0D807240B"><p>​Really?</p></div>" ows_MetaInfo="1;#" ows__ModerationStatus="0" ows__Level="1" ows_ID="1" ows_UniqueId="1;#{336518DC-B806-4DFB-9483-AB8DBB6258B6}" ows_owshiddenversion="1" ows_FSObjType="1;#1" ows_Created="2012-01-09 14:16:29" ows_PermMask="0x7fffffffffffffff" ows_Modified="2012-01-09 14:16:29" ows_FileRef="1;#Lists/Team Discussion/Bite Me"/>
</rs:data>
</listitems>
</GetListItemsResult>
</GetListItemsResponse>
</soap:Body>
</soap:Envelope>
EDIT: Each of the above posts should also have a reply.
I eventually found the magic query. It seems sub folders are only returned when you add a query based on date, i.e. this soap request works.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
<soapenv:Header/>
<soapenv:Body>
<soap:GetListItems>
<!--Optional:-->
<soap:listName>969E0130-5727-4E7D-A908-B3A5BC447E24</soap:listName>
<soap:viewFields>
<ViewFields>
<FieldRef Name='Title'/>
<FieldRef Name='Created'/>
<FieldRef Name='Author'/>
<FieldRef Name='Body'/>
</ViewFields>
</soap:viewFields>
<soap:query>
<Query>
<Where>
<Geq>
<FieldRef Name='Created' />
<Value Type='DateTime'>2010-08-20T14:00:00</Value>
</Geq>
</Where>
<OrderBy><FieldRef Name='ThreadIndex' Ascending='true' /></OrderBy>
</Query>
</soap:query>
<soap:queryOptions>
<QueryOptions>
<ViewAttributes Scope="RecursiveAll" IncludeRootFolder="False" />
</QueryOptions>
</soap:queryOptions>
</soap:GetListItems>
</soapenv:Body>
</soapenv:Envelope>
The essential parts are the query element with the date and the query option to specify the query is recursive.
imho shouldn't need the query as it should return everything by default.
The folder option listed in the other article didn't make any difference for me.
Have you checked out this article:
How to access SharePoint's Discussion Board using Web Services
http://geekswithblogs.net/kobush/archive/2007/03/12/108545.aspx