Hi,
We like to connect to Salesforce via SOAP using ABL (Openedge 10.2B; using Fiddler for debugging). Can anybody provide sample code? Or the entire SOAP message of a service request?
A connect to the Salesforce Web Service is working in two steps:
1. Access this Service via WSDL using UserID and Password + Token. The first request is login() which results in a temporary ServerURL and SessionID.
2. Use this temporary connect information to reconnect.
We are currently connecting successfully, but fail to send a proper service request (e.g. GetUserInfo() ).
Request:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header><ns0:SessionHeader xmlns:ns0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><ns0:sessionId>00D1a000000aEEi!ARQAQG80_DJY_nmJG68qiJOX7U_o6rBPFK8cSVNrrR8z.K8rs9JgOB91MeceB21OiuHwFgGPVwiNfj6oi4C4cYrFonF.VQYe</ns0:sessionId><ns1:serverURL xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">https://na24.salesforce.com/services/Soap/c/34.0/00D1a000000aEEi/0DF1a000000TPPx</ns1:serverURL></ns0:SessionHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns0:getUserInfo xmlns:ns0="urn:enterprise.soap.sforce.com"/></SOAP-ENV:Body></SOAP-ENV:Envelope>
Result:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Client</faultcode><faultstring>Element {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}serverURL invalid at this location</faultstring></soapenv:Fault></soapenv:Body></soapenv:Envelope>
I wrote a Progress Salesforce library quite a while ago
that I've used at several customers sites and I know other developers that have used it
but I haven't updated or used it in a long time in case there are any changes to the api.
The library is part of the Progress Standard Libraries project at the oehive.org
Download the project zip file and look at the sfdc/ directory.
Hope this helps,
Alon
I wrote a Progress Salesforce library quite a while ago
that I've used at several customers sites and I know other developers that have used it
but I haven't updated or used it in a long time in case there are any changes to the api.
The library is part of the Progress Standard Libraries project at the oehive.org
Download the project zip file and look at the sfdc/ directory.
Hope this helps,
Alon
Thanks, Alon!!!
As expected the service request was not formatted correctly . The correct request should look something like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="schemas.xmlsoap.org/.../" xmlns:xsi="www.w3.org/.../XMLSchema-instance"><SOAP-ENV:Header><ns0:SessionHeader xmlns:ns0="urn:enterprise.soap.sforce.com"><ns0:sessionId>00D1a000000aEEi!ARQAQOhNFKOBEvs86aTGH0FPVp9AT_DDF8LMZbREIup9ydZBXx_PrWYh7dHSu5dMRMNKBZsEF_YrtacHzP7DPtFyqXReI1aE</ns0:sessionId></ns0:SessionHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns0:getUserInfo xmlns:ns0="urn:enterprise.soap.sforce.com"/></SOAP-ENV:Body></SOAP-ENV:Envelope>
My version of the Request Handler Procedure is:
PROCEDURE ySFReqHandler :
/* Description ---------------------------------------------------------------*/
/* */
/* SOAP Message Request Handler */
/* */
/* Notes ---------------------------------------------------------------------*/
/* */
/* 'SessionHeader' and 'sessionId' are case-sensitive elements! */
/* */
/* Parameters ----------------------------------------------------------------*/
/* */
/* <none> */
/* */
/* Examples ------------------------------------------------------------------*/
/* */
/* */
/* */
/*----------------------------------------------------------------------------*/
define output parameter phHeader as handle.
define input parameter pcNamespace as character.
define input parameter pcLocalNS as character.
define output parameter plDeleteOnDone as logical.
define variable hHeaderEntryRef as handle no-undo.
define variable hXDoc as handle no-undo.
define variable hXRoot as handle no-undo.
define variable hXElement as handle no-undo.
define variable hXText as handle no-undo.
delete object ghHeader no-error.
/* Build header XML */
create x-document hXDoc.
create x-noderef hXRoot.
create x-noderef hXElement.
create x-noderef hXText.
create soap-header ghHeader.
create soap-header-entryref hHeaderEntryRef.
ghHeader:add-header-entry(hHeaderEntryRef).
hXDoc:create-node-namespace(hXRoot, 'urn:enterprise.soap.sforce.com':U, 'SessionHeader':U, 'element':U).
hXDoc:append-child(hXRoot).
hXDoc:create-node-namespace(hXElement, 'urn:enterprise.soap.sforce.com':U, 'sessionId':U, 'element':U).
hXDoc:create-node (hXText, ?, 'text':U).
hXRoot:append-child (hXElement).
hXElement:append-child (hXText).
hXText:node-value = gcySFSessionId.
hHeaderEntryref:set-node (hXRoot).
assign
phHeader = ghHeader
plDeleteOnDone = yes
.
finally:
delete object hHeaderEntryRef no-error.
delete object hXDoc no-error.
delete object hXRoot no-error.
delete object hXElement no-error.
delete object hXText no-error.
end. /* finally */
end procedure. /* ReqHandler */
PS: to add a bit more information to this post. This is my current version of the connect procedure
/* Description ---------------------------------------------------------------*/
/* */
/* Initial Connect to Salesforce SOAP Web Service */
/* */
/* Notes ---------------------------------------------------------------------*/
/*
http://knowledgebase.progress.com/articles/Article/P140169?popup=true
https://developer.salesforce.com/forums/?id=906F00000008t9TIAQ
http://www.oehive.org/project/lib (see slib/sfdc)
*/
/* Parameters ----------------------------------------------------------------*/
/* */
/* <none> */
/* */
/* Examples ------------------------------------------------------------------*/
/*
{basis/incl/b__alp00.cdf}
{y/vert/incl/yv_sf_00.lib}
define variable cResult as longchar no-undo.
run ySFConnect.
run getUserInfo in ghSForce (output cResult).
*/
/*----------------------------------------------------------------------------*/
define variable lcResult as longchar no-undo.
define variable hDataset as handle no-undo.
do
on error undo, retry:
/* reset all variables */
{y/vert/incl/yv_sf_01.if}
if retry then
return error.
/* Connect to Web Service */
create server ghSFWebService.
ghSFWebService:connect(substitute ("-WSDL '&1'":U, search ('salesforce.wsdl':U))) no-error.
if error-status:error then
undo, retry.
run Soap set ghSForce on ghSFWebService.
/* login at Salesforce and get temporary connection info */
run login in ghSForce ('user':U,'password-and-token':U, output lcResult).
assign
gcySFServerURL = cyExtractStringBetweenKeywords (lcResult, '<ServerURL>':U, '</ServerURL>':U)
gcySFSessionId = cyExtractStringBetweenKeywords (lcResult, '<SessionId>':U, '</SessionId>':U)
.
/* reconnect to new URL */
delete object ghSForce.
ghSFWebService:disconnect().
ghSFWebService:connect(substitute ("-WSDL '&1' -Binding SoapBinding -SOAPEndpoint '&2' -SOAPEndpointUserid '&3'":U,
search ('salesforce.wsdl':U),
gcySFServerURL,
gcySFSessionId
)).
run Soap set ghSForce on ghSFWebService.
ghSForce:set-callback-procedure ("REQUEST-HEADER", "ySFReqHandler"). /* SOAP-Header procedure for future service requests */
end. /* do */
finally:
delete object hDataset no-error.
end. /* finally */
end procedure. /* yConnectEMM */
P.S. the standard libraries project includes a few other useful libraries, like, a google api, a powerful backup system, a query optimizer baseline, as well as low level libraries, like, zip, http, date, math, timing events, code parsing etc. libraries. all libraries are free and open source.
Hi
I'm having trouble making the salesforce ws create call.
Can you send me how you were able to place the call through your program?
Below is the template I'm using.
By the time, thanks
/* Description ---------------------------------------------------------------*/
/* */
/* SOAP Message Request Handler */
/* */
/* Notes ---------------------------------------------------------------------*/
/* */
/* 'SessionHeader' and 'sessionId' are case-sensitive elements! */
/* */
/* Parameters ----------------------------------------------------------------*/
/* */
/* <none> */
/* */
/* Examples ------------------------------------------------------------------*/
/* */
/* */
/* */
/*----------------------------------------------------------------------------*/
DEFINE VARIABLE username AS CHARACTER NO-UNDO.
DEFINE VARIABLE password AS CHARACTER NO-UNDO.
DEFINE VARIABLE result AS LONGCHAR NO-UNDO.
DEFINE VARIABLE cUserId AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSessionId AS CHARACTER NO-UNDO.
DEFINE VARIABLE cServerUrl AS CHARACTER NO-UNDO.
DEFINE VARIABLE hWebService AS HANDLE NO-UNDO.
DEFINE VARIABLE hWebService2 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoap AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoap2 AS HANDLE NO-UNDO.
DEFINE VARIABLE cResult AS CHARACTER NO-UNDO.
/*1*/
/* Define local variables */
DEFINE VARIABLE hWebSrvc AS HANDLE.
DEFINE VARIABLE hPortType AS HANDLE.
DEFINE VARIABLE hXdoc AS HANDLE.
DEFINE VARIABLE hXnoderef1 AS HANDLE.
DEFINE VARIABLE hXnoderef2 AS HANDLE.
DEFINE VARIABLE hXtext AS HANDLE.
DEFINE VARIABLE xroot AS HANDLE.
DEFINE VARIABLE lcHeader AS LONGCHAR NO-UNDO.
DEFINE VARIABLE g_header AS HANDLE.
DEFINE VARIABLE hRootField AS HANDLE NO-UNDO.
DEFINE VARIABLE parameters1 AS LONGCHAR NO-UNDO.
DEFINE VARIABLE parameters2 AS LONGCHAR NO-UNDO.
assign username = {1}
password = {2}.
/* ------------------------------------------------------------------------------------ */
CREATE SERVER hWebService.
/* ------------------------------------------------------------------------------------ */
hWebService:CONNECT("-WSDL 'salesforce.wsdl'").
/* ------------------------------------------------------------------------------------ */
RUN Soap SET hSoap ON hWebService.
/* ------------------------------------------------------------------------------------ */
ASSIGN parameters1 =
'<login xmlns:ns0="urn:enterprise.soap.sforce.com">' +
'<username>' + username + '</username>' +
'<password>' + password + '</password>' +
'</login>'.
/* ------------------------------------------------------------------------------------ */
/* Procedure invocation of login operation. */
RUN login IN hSoap(INPUT parameters1, OUTPUT parameters2).
/* ------------------------------------------------------------------------------------ */
ASSIGN cResult = STRING(parameters2)
cSessionId = SUBSTRING(cResult,INDEX(cResult,"<sessionId>") + 11,LENGTH(cResult))
cSessionId = SUBSTRING(cSessionId,1,INDEX(cSessionId,"</sessionId>") - 1)
cServerUrl = SUBSTRING(cResult,INDEX(cResult,"<serverUrl>") + 11,LENGTH(cResult))
cServerUrl = "-WSDL " + SUBSTRING(cServerUrl,1,INDEX(cServerUrl,"</serverUrl>") - 1) + ".wsdl"
cUserId = SUBSTRING(cResult,INDEX(cResult,"<userId>") + 8,LENGTH(cResult))
cUserId = SUBSTRING(cUserId,1,INDEX(cUserId,"</userId>") - 1).
/* ------------------------------------------------------------------------------------ */
assign cServerUrl = "-WSDL " + 'salesforce.wsdl' +
" -SOAPEndpoint " + cServerUrl +
" -SOAPEndpointUserid " + cUserId +
" -SOAPEndpointPassword " + password.
/* ------------------------------------------------------------------------------------ */
/* Build global SOAP request header */
/* ------------------------------------------------------------------------------------ */
CREATE SERVER hWebService2.
/* ------------------------------------------------------------------------------------ */
hWebService2:CONNECT(cServerUrl).
/* ------------------------------------------------------------------------------------ */
RUN Soap SET hSoap2 ON hWebService2.
hSoap2:set-callback-procedure("REQUEST-HEADER", "ySFReqHandler").
/* ------------------------------------------------------------------------------------ */
assign parameters1 =
'<ns0:create xmlns:ns0="urn:enterprise.soap.sforce.com">' +
'<ns0:sObjects type="Lead">' +
'<LastName>Gilma Silva2</LastName>' +
'<Company>ACME</Company>' +
'<Status>Pesquisa/consideração2</Status>' +
'<FirstName>GilmaLeadTeste2</FirstName>' +
'<Email>Gilmasilva2@teste.com</Email>' +
'<phone>(11) 6876-54321</phone>' +
'</ns0:sObjects>' +
'</ns0:create>'
.
RUN create IN hSoap2(INPUT parameters1, OUTPUT parameters2).
copy-lob from parameters2 to file 'c:\temp\saida.xml' convert target codepage 'UTF-8'.
PROCEDURE ySFReqHandler :
/* Description ---------------------------------------------------------------*/
/* */
/* SOAP Message Request Handler */
/* */
/* Notes ---------------------------------------------------------------------*/
/* */
/* 'SessionHeader' and 'sessionId' are case-sensitive elements! */
/* */
/* Parameters ----------------------------------------------------------------*/
/* */
/* <none> */
/* */
/* Examples ------------------------------------------------------------------*/
/* */
/* */
/* */
/*----------------------------------------------------------------------------*/
define output parameter phHeader as handle.
define input parameter pcNamespace as character.
define input parameter pcLocalNS as character.
define output parameter plDeleteOnDone as logical.
define variable hHeaderEntryRef as handle no-undo.
define variable hXDoc as handle no-undo.
define variable hXRoot as handle no-undo.
define variable hXElement as handle no-undo.
define variable hXText as handle no-undo.
define variable ghHeader as handle no-undo.
delete object ghHeader no-error.
/* Build header XML */
create x-document hXDoc.
create x-noderef hXRoot.
create x-noderef hXElement.
create x-noderef hXText.
create soap-header ghHeader.
create soap-header-entryref hHeaderEntryRef.
ghHeader:add-header-entry(hHeaderEntryRef).
hXDoc:create-node-namespace(hXRoot, 'urn:enterprise.soap.sforce.com':U, 'SessionHeader':U, 'element':U).
hXDoc:append-child(hXRoot).
hXDoc:create-node-namespace(hXElement, 'urn:enterprise.soap.sforce.com':U, 'sessionId':U, 'element':U).
hXDoc:create-node (hXText, ?, 'text':U).
hXRoot:append-child (hXElement).
hXElement:append-child (hXText).
hXText:node-value = cSessionId.
hHeaderEntryref:set-node (hXRoot).
ASSIGN phHeader = ghHeader
plDeleteOnDone = YES.
finally:
delete object hHeaderEntryRef no-error.
delete object hXDoc no-error.
delete object hXRoot no-error.
delete object hXElement no-error.
delete object hXText no-error.
END.
/* finally */
end procedure. /* ReqHandler */
What version of Openedge?
I'm not sure if this is your problem but SalesForce has required TLS 1.2 for at least a year now. Versions of Progress prior to 11.6 did not support this.