function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Alexander KrykunAlexander Krykun 

How to make soap call properly

I have 2 org ad I want to provide making calls from one 1 org to another
I have allredy generated wsdl file for my soap webservice 
Original   class  simply looks like

global class SoapTest {
    webservice static String getGreeting() {
        return 'Hi, pal!';
    }
}

My external  call now loooks like:

soapTestParse.SoapTest sp = new soapTestParse.SoapTest();
String output = sp.getGreeting();
System.debug(output);

as a result I'mI getting 

System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session faultcode=sf:INVALID_SESSION_ID faultactor=


I have been reading bunch of posts with the same problem but I still don't know the proper way to solve it

I saw such snippets of code 

in developer guide:

stub.inputHttpHeaders_x.put('Authorization', 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
 

but How can I dynamically get this token? Even if I hard code session id of target org, error remains the same.

In another poste

partnerSoapSforceCom.LoginResult partnerLoginResult = myPartnerSoap.login('karnashiva@cognizant.com.dev', 'Password123'); 
soapSforceComSchemasClassAccountins.SessionHeader_element webserviceSessionHeader = new soapSforceComSchemasClassAccountins.SessionHeader_element(); 
webserviceSessionHeader.sessionId = partnerLoginResult.sessionId;

I don't have neither login method no loginresult class in my generated from wsdl apex class

In another poste

ws.inputHttpHeaders_x = new Map <String, String>(); 
String b64_string = EncodingUtil.base64Encode(Blob.valueOf('<user_name>:<password>')); ws.inputHttpHeaders_x.put('Authorization', 'Basic ' + b64_string);
it still doesn't work

Can someone help, or give some tips or proper examples of soap callouts?
Best Answer chosen by Alexander Krykun
Daniel BallingerDaniel Ballinger
If you have securely stored credentials for the target Salesforce org then you can use the Partner API to perform the login call and get a valid SessionId and server URL that you can then use with your web service.
 
partnerSoapSforceCom.Soap partner = new partnerSoapSforceCom.Soap();
partnerSoapSforceCom.LoginResult lr=partner.login('user@example.com', 'Password123'++'securityToken');


// Example of using the session details to call the Partner API
partnerSoapSforceCom.SessionHeader_element header=new partnerSoapSforceCom.SessionHeader_element();
header.sessionId=lr.sessionId;
partner.SessionHeader=header;
partner.endpoint_x = lr.serverUrl;
partnerSoapSforceCom.QueryResult qr = partner.Query('Select Id, Name from Account limit 1');
System.debug('Number of Query results:' + qr);
sobjectPartnerSoapSforceCom.sObject_x result1 = qr.records[0];
System.debug(result1);

So you would likely make the same login call from the first two lines against the Partner API and they create the same SessionHeader_element for your soapTestParse.SoapTest instance.

All Answers

John Pipkin 14John Pipkin 14
Alexander, 

Any time that you are connecting from one SFDC org to another, you have to authenticate first. OAuth is easiest to implement. See https://help.salesforce.com/HTViewHelpDoc?id=remoteaccess_authenticate.htm for help on OAuth. OAuth will send back an access_token that you can use for subsequent calls into the connected org in the http header.

Hope that helps.
Daniel BallingerDaniel Ballinger
If you have securely stored credentials for the target Salesforce org then you can use the Partner API to perform the login call and get a valid SessionId and server URL that you can then use with your web service.
 
partnerSoapSforceCom.Soap partner = new partnerSoapSforceCom.Soap();
partnerSoapSforceCom.LoginResult lr=partner.login('user@example.com', 'Password123'++'securityToken');


// Example of using the session details to call the Partner API
partnerSoapSforceCom.SessionHeader_element header=new partnerSoapSforceCom.SessionHeader_element();
header.sessionId=lr.sessionId;
partner.SessionHeader=header;
partner.endpoint_x = lr.serverUrl;
partnerSoapSforceCom.QueryResult qr = partner.Query('Select Id, Name from Account limit 1');
System.debug('Number of Query results:' + qr);
sobjectPartnerSoapSforceCom.sObject_x result1 = qr.records[0];
System.debug(result1);

So you would likely make the same login call from the first two lines against the Partner API and they create the same SessionHeader_element for your soapTestParse.SoapTest instance.
This was selected as the best answer
Alexander KrykunAlexander Krykun
As I understood, I need to generate partner wsdl and generate then apex classes from this wsdl  on first org. But now I'm getting 
Apex Generation Failed
Unsupported schema type: {http://www.w3.org/2001/XMLSchema}anyType
Daniel BallingerDaniel Ballinger
Have a look at our free FuseIT SFDC Explorer version of Wsdl2Apex (http://www.fishofprey.com/2014/11/dreamforce-2014-presentation-improved.html). It can handle or at least not fail on a number of WSDL features that the default version can't. It will also allow you to just bring in the minimal web methods.

Another alternative is to just make the requried API calls directly with an HTTP Post.