Monday 19 March 2012

OSB access to salesforce.com

Some time ago I had a request to connect a file with salesforce.com. The tool of choice was Oracle Service Bus, first without any special adapter. So I had to investigate into the salesforce.com way of using web services and how I can approach this challenge.

First of all we need an account with salesforce.com. With this account we can access the Web Services API through Profile -> Setup -> API. Here we need to download the Enterprise WSDL


You can find more details to this here salesforce.com Documentation.

Now we import the WSDL into the Oracle Service Bus. As written in the docs
Before invoking any other calls, a client application must first invoke the login() call to establish a session with the login server, set the returned server URL as the target server for subsequent API requests, and set the returned session ID in the SOAP header to provide server authorization for subsequent API requests.
This means for Oracle Service Bus that we have to use an additional "Service Callout" before calling any other operation. With this in mind, it might be a good idea to store the session information for subsequent calls. As the Oracle Service Bus is stateless, this job could be achieved by using a java callout with a class variable storing the SF session ID.

 package client;  
 public class LoginStore {  
  private static String sessionID = null;  
  private static String serverURI = null;  
  public LoginStore() {  
   super();  
  }  
  public LoginStore(String sessionID ,String serverURI) {  
   super();  
   this.sessionID = sessionID;  
   this.serverURI = sessionID;  
  }  
  public static void setSessionID(String sessionID) {  
   LoginStore.sessionID = sessionID;  
  }  
  public static String getSessionID() {  
   return sessionID;  
  }  
  public static void setServerURI(String serverURI) {  
   LoginStore.serverURI = serverURI;  
  }  
  public static String getServerURI() {  
   return serverURI;  
  }  
 }  

I am also storing the Server URI for the subsequent calls.

Lets have a look into a Proxy Service to Update data on salesforce.com.



Before calling the API function we have a stage (login) with a publish action to the Login function proxy (loginPS).
The two Java callouts read the values from the "LoginStore"into OSB variables.

The LoginPS first checks if we already have a sessionID, or if it is necessary to first login and then store the results.


The assign action contains the login data in the following form

 <urn:login>  
    <urn:username>steffen.miller@oracle.com</urn:username>  
    <urn:password>SecretPassword8jlSMFQ41MjeNmIv84BZEkfpO</urn:password>  
 </urn:login>  

The password consists of two parts, the password itself, here "SecretPassword" and a security token which was defined by salesforce.com and is found in the mail after user creation, or could be regenerated by changing the password, or invalidating the security token "Reset My Security Token". Than a new token is send by mail.

Now putting it all together, I need a Business Service offering the Operations available through the Enterprise Web service enterprise.wsdl, doing the connection work to salesforce.com. This Business Service is called in the above
CallSF_PS in the "route 2 salesforce.com" routing node.

With the above Insert statement the $header object is amended with the following element

 <urn:SessionHeader>  
     <urn:sessionId>{ $sessionID }</urn:sessionId>  
 </urn:SessionHeader>  

And the Routing Options action changes the Server URI to the dynamic URI returned from the login process.

Finally, the service can be tested with test console.

The complete OSB project can be downloaded here

16 comments:

  1. Hi Steffen,

    Many thanks for writing such a wonderful blog.

    I am having an issue while calling secured salesforce webservice. Could you please provide steps how to configure weblogic & proxy service & business service for secure salesforce web service.

    Thanks in advance.

    ReplyDelete
  2. Hi,
    this is a "secured" WS call to SF.
    https://login.salesforce.com/services/Soap/c/20.0

    I am going to upload the complete project in the next hour.

    Regards
    Steffen

    ReplyDelete
  3. Thanks Miller, thanks for your quick response, can you through some light on the settings in weblogic server e.g. how to create a keystore in weblogic, ssl etc.

    I did all that but I am getting issues while calling secured webservice of salesforce, certainly there is some issue with configuration at my end. So, if you can elaborate some steps on how to configure that.

    Many thanks once again.

    ReplyDelete
  4. Hi, there is no special setup for the call to the secured https SF webservice. Or do you want to achieve a two-way SSL communication with SF ?

    ReplyDelete
  5. Frankly speaking I dont know much about SSL, I just want to get the desired result as in your example. Also have you used any service key provider in your POC.

    ReplyDelete
  6. No service key provider used in this example. The login is done "hardcoded" inside the proxy against SF https web service. It is necessary to have a user and the users password and token. The SF server returns a SessionID which has to be send with every subsequent call. If the proxy itself should offer an SSL service, we have another game. This might help for the second one http://bit.ly/Hve2mb

    ReplyDelete
  7. This 11g? Cannot import into 10gR3.

    ReplyDelete
  8. Hi steffen,

    Thanks for the helpful article!!!

    After login, how do I invoke other Saleforce operations such as update?

    Thank you,
    Daniel

    ReplyDelete
  9. Hi Steffen,

    Excellent post on salesforce with OSB.

    I could use this sample and replicate in my project.
    Issue which I'm getting is whenever requestes are not submitted to OSBfor a while(lets say 10 hrs) ,session is getting expired but thats not cleared in the java class unless we re-start the OSB server.

    PLease provide your inputs on how to handle this situation.

    Regards,
    N

    ReplyDelete
  10. Oracle has recently released Cloud Adapter for SalesForce.com. This is the perfect way to connect OSB/BPEL to SalesForce.

    Thanks,
    Ashish Arya

    ReplyDelete
  11. Many thanks for writing this nice article.

    I am facing following issue, urn:Prefix not defined in static context

    I am getting this error while setting following in the header element


    { $sessionID }


    Thanks

    Harvinder

    ReplyDelete
  12. Someone was asking about SSL, my salesforce interface from OSB was working good without any configuration on keystore and it started failing once I moved to "Custom" keystore from Demo keystore for some other project?
    how do we solve this?
    Also with Demo store is Weblogic not authenticating the certificates from salesforce even though it is a https web sercvice?

    ReplyDelete
  13. Request Document






    SELECT FirstName, LastName FROM Contact




    Response Document

    The invocation resulted in an error: .



    soapenv:Server

    General_error: com.bea.wli.sb.pipeline.PipelineException



    General_error

    com.bea.wli.sb.pipeline.PipelineException


    Route 2 salesforce.com

    _onErrorHandler-5980715324579848572-34440b47.13634bd1ea7.-7fd1

    request-pipeline
    true







    Can anyone give me an explanation of this error and help me to solve it?

    Thanks in advance

    ReplyDelete
  14. Will this works in OSB 12c or in SOA 12c ? We have to call SF as soap call, not supposed to use SF adapter.

    ReplyDelete
  15. Hi Steffen,

    Nice Post. Could you please let us know how the session id expiration is handled here?

    ReplyDelete