July 29, 2010

Tolerado SFDC WSC Helper APIs

I am researching on how to best use & integrate “WSC” with Tolerado. This research mainly focuses on

  • How to preserve and reuse a single sfdc login session across the all the WSDLs. This should again go in transparent fashion as with Tolerado for Apache Axis.
  • How to give an flexible+transparent interface to either login via Enterprise or Partner WSDL and then play with Metadata and Apex WSDL if required.
  • Keep possibility of Session caching open.

So during all that research, I came out with some Helper classes, that will anyway become part of Tolerado WSC framework, but I am releasing those as independent Java API classes. This will benefit others playing with WSC and who are not yet on Tolerado.

For this reason, I am sharing a helper Class/API for WSC in this post. This helper class is named “WSCSession” and it helps managing WSC session in a smart & easy way.

Class - WSCSession

Following are the highlights of WSCSession Class.

  • WSCSession allows you to flexibly login either via Partner or Enterprise WSDL. The best part is it doesn’t depends on either Partner or Enterprise WSDL2Java classes. So if you are working on Enterprise WSDL, you don’t need to include WSDL2Java classes for Partner WSDL in classpath. It internally works on dynamic class loading to ensure right WSC Connectors are used to create SFDC Sessions.
  • Gives easy API to obtain Service Endpoints for all Salesforce WSDLs like Partner, Enterprise, Metadata and Apex WSDL.  For ex.
    • public String getSessionId(); // returns reusable session id, that works across all wsdls
    • public String getMetadataServerUrl(); // Metadata Service Endpoint
    • public String getPartnerServerUrl(); // Partner Service Endpoint
    • public String getEnterpriseServerUrl(); // Enterprise Service Endpoint
    • public String getApexServerUrl(); // Apex Service Endpoint

Code Snippets - How WSCSession makes life easy with WSC ?

Now we will explore how to create a WSCSession instance and use it with all the WSDLs.

Creating WSCSession using Enterprise WSDL for login
// Note, we just specified Login WSDL is Enterprise
WSCSession session = new WSCSession(LoginWSDL.Enterprise, "user", "password");
Creating WSCSession using Partner WSDL for login
// Note, we just specified Login WSDL is Partner
WSCSession session = new WSCSession(LoginWSDL.Partner, "user", "password");

We can start playing with code samples below, once WSCSession is created in either of the above mentioned way i.e. by Enterprise or Partner WSDL.

Partner WSDL Sample – Creating Contact Record
static void doPartner(WSCSession session)
        throws ConnectionException {
    // Create new Partner Connection
    ConnectorConfig config = new ConnectorConfig();
    config.setManualLogin(true);
    // Parter Service Endpoint used from WSCSession
    config.setServiceEndpoint(session.getPartnerServerUrl());
    // SFDC Session Id pulled from WSCSession
    config.setSessionId(session.getSessionId());
    PartnerConnection partnerConn = Connector.newConnection(config);      

    // Create a new Contact
    SObject contact = new SObject();
    contact.setType("Contact");
    contact.setField("FirstName", "Abhinav");
    contact.setField("LastName", "Gupta");
    SaveResult[] create = partnerConn.create(new SObject[] { contact });
    for (SaveResult saveResult : create) {
        if (!saveResult.isSuccess()) {
            throw new RuntimeException(
                    "Failed to save contact via Partner WSDL");
        }
    }
    System.out.println("Partner-WSDL : Save successfully done");
}
Metadata WSDL Sample – Describe Metadata
static void doMeta(WSCSession session) throws ConnectionException {
    // Create Metadata Connection
    ConnectorConfig metadataConfig = new ConnectorConfig();
    // SFDC Session Id pulled from WSCSession
    metadataConfig.setSessionId(session.getSessionId());
    // Metadata Service Endpoint used from WSCSession
    metadataConfig.setServiceEndpoint(session.getMetadataServerUrl());
    MetadataConnection metadataConnection = com.sforce.soap.metadata.Connector
            .newConnection(metadataConfig);

    // Try describing the metadata
    DescribeMetadataResult describeMetadata = metadataConnection
            .describeMetadata(15.0);
    System.out
            .println("Metadata WSDL : OrgName from describeMetadata() call"
                    + describeMetadata.getOrganizationNamespace());
}
Apex WSDL Sample – Running All Tests
static void doApex(WSCSession session) throws ConnectionException {
    // Create Apex Connection
    ConnectorConfig apexConfig = new ConnectorConfig();
    // SFDC Session Id pulled from WSCSession
    apexConfig.setSessionId(session.getSessionId());
    String apexEndpoint = session.getApexServerUrl();
    // Metadata Service Endpoint used from WSCSession
    apexConfig.setServiceEndpoint(apexEndpoint);
    SoapConnection apexConnection = com.sforce.soap.apex.Connector
            .newConnection(apexConfig);

    // Run All Tests in the org
    RunTestsRequest runTestsRequest = new RunTestsRequest();
    runTestsRequest.setAllTests(true);
    runTestsRequest.setNamespace("");
    RunTestsResult runTests = apexConnection.runTests(runTestsRequest);
    System.out.println(" Apex-WSDL: NumTestsRun :  "
            + runTests.getNumTestsRun());
}
Enterprise WSDL Sample – Querying Contact Record
static void doEnterprise(WSCSession sessionFactory)
        throws ConnectionException {
    // Create Enterprise Connection		
    ConnectorConfig entCfg = new ConnectorConfig();
    entCfg.setManualLogin(true);                
    // Enterprise Service Endpoint used from WSCSession
    entCfg.setServiceEndpoint(sessionFactory.getEnterpriseServerUrl());
    // SFDC Session Id pulled from WSCSession
    entCfg.setSessionId(session.getSessionId());
    EnterpriseConnection entConn = com.sforce.soap.enterprise.Connector
            .newConnection(entCfg);		

    // Enterprise WSDL for query
    QueryResult queryResults = entConn
            .query("SELECT Id, FirstName, LastName FROM Contact LIMIT 1");
    if (queryResults.getSize() > 0) {
        Contact c = (Contact) queryResults.getRecords()[0];
        System.out.println("EnterPrise WSDL : Queried Contact Name: "
                + c.getFirstName() + " " + c.getLastName());
    }
}

Running the Code Samples - WSCSession and Sample Source

WSCSession class and sample code is checked in as part of Tolerado WSC project. For these WSC Helper Samples, their is a new Eclipse Java project(link to SVN code base) that you can directly checkout from SVN to start playing with directly in Eclipse. Just locate a properties file name “login.props” in the downloaded source and set your SFDC credentials in this file. All the sample code will automatically use the credentials in login.props file. The samples file is with name “WSCSessionSample”.

Please let me know any bugs or issues, if you faced.