I have an imported WSDL from SalesForce and I am trying to send a login-request to the SalesForce-servers via InterSystems. The login requires a username and a password in the body, and an organizationId in the header. I am having trouble filling the organizationId in the header.
Via SoapUI I can send a successfull message to the SalesForce-servers. The message should look like this:
> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
> <soapenv:Header>
> <urn:LoginScopeHeader>
> <urn:organizationId>MyOrganizationId</urn:organizationId>
> </urn:LoginScopeHeader>
> </soapenv:Header>
> <soapenv:Body>
> <urn:login>
> <urn:username>MyUsername</urn:username>
> <urn:password>MyPassword</urn:password>
> </urn:login>
> </soapenv:Body>
> </soapenv:Envelope>
In InterSystems Studio, I firstly imported the WSDL using the Studio's Soap Add-in. Among other things, this gave the following results:
1. A business operation class containing the login method:
>
{
Set ..Adapter.WebServiceClientClass = "SforceService.Soap"
Set tSC = ..Adapter.InvokeMethod("login",.result,pRequest.username,pRequest.password) Quit:$$$ISERR(tSC) tSC
Set tSC = pRequest.NewResponse(.pResponse) Quit:$$$ISERR(tSC) tSC
Set pResponse.result=$get(result)
Quit $$$OK
}</p></blockquote>
>
>
> 2. A webclient class containing the login-method (proxy?_ >
> >>>
/// Login to the Salesforce.com SOAP Api
Method login(username As %String(REQUIRED=1), password As %String(REQUIRED=1)) As SforceService.tns.LoginResult(XMLNAME="result") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
Quit ..WebMethod("login").Invoke($this,"",.username,.password)
}</p></blockquote> > >> 3. The webclient class also contains an XdataMap noting that the LoginScopeHeader may be included with the login-request. The LoginScopeHeader contains the organizationId. >
> >>> ... >
> >>
<method name="login">
<request>
<header name="LoginScopeHeader" class="SforceService.tns.LoginScopeHeader"/>
</request>
</method></p> > >> ... >
</blockquote> > >> As you can see the Header is referred to, but not included in as a parameter in the method. >
> >> Of course, I need to expand the method so that I can pass organizationId as a parameter. A first step in to this solution would be to hard code the organizationId in login-request. In the InterSystems documentation I found an example how to add the header using the HeadersOut-function ( https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GSOAP_header ). I implemented this in the web client class as follows: >
> >>>
/// Login to the Salesforce.com SOAP Api
Method login(username As %String(REQUIRED=1), password As %String(REQUIRED=1)) As SforceService.tns.LoginResult(XMLNAME="result") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
Set header=##class(SforceService.tns.LoginScopeHeader).%New()
Set header.organizationId = "MyOrganizationId"
Do ..HeadersOut.SetAt(header,"SforceService.tns.LoginScopeHeader")
Quit ..WebMethod("login").Invoke($this,"",.username,.password)
}</p></blockquote> > >> However, when I compile and run this code and view the soap log the header is still missing:
> >
>>> >> 08/16/2017 10:55:13 *********************
>
Output from Web client with SOAP action =
> >
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body><login xmlns="urn:enterprise.soap.sforce.com"><username xsi:type="s:string">test</username><password xsi:type="s:string">test</password></login></SOAP-ENV:Body>
</SOAP-ENV:Envelope> >> What did I do wrong? >
> >> >
</body></html>