This post explains how Tolerado improves the Java client code for using Salesforce web services.
Why Client Code improvement is required ?
Developers are always too concerned about many things, like making the Web Service call work right for them and implementing the biz requirements. So handling exceptions and giving them proper treatment is mostly not a priority. Developers usually check the API docs/samples and production ready product usually evolves from the foundation laid by those sample codes.
So, Tolerado jumps in here to touch the areas often ignored in web service programming.
Code Samples
Here we will try touching areas of common programming issues and how Tolerado would fix them.
Sample 1 : Making Partner/Metadata/Apex Calls
When working Salesforce Axis client stubs, following are 2 very common scenarios/exceptions, where its possible to recover from errors but the code crashed :
Exception 1: Connection timeout or Unknownhost Error: This error might temporarily come in your internet connection because of some DNS/internet issues.
Exception 2: Service temporarily down: Again on getting this error, we are failing fast in above code samples.
// Code sample that shows, the web service exception
// being caught and eaten
QueryResult qr = null;
try {
// All your code to create the binding and set the correct headers
// ....
// ...
binding = (SoapBindingStub) new SforceServiceLocator().getSoap();
// ...
LoginResult loginResult = binding.login(userName, password);
binding._setProperty(SoapBindingStub.ENDPOINT_ADDRESS_PROPERTY,
loginResult.getServerUrl());
SessionHeader sh = new SessionHeader();
sh.setSessionId(loginResult.getSessionId());
binding.setHeader(new SforceServiceLocator().getServiceName()
.getNamespaceURI(), "SessionHeader", sh);
qr = binding.query("select FirstName, LastName from Contact");
// ...
// process the results within QueryResult
// ...
}catch (Exception ex) {
// No recovery, just log the message.
System.out.println(
"\nFailed to execute query successfully, error message was: \n"
+ ex.getMessage());
}
After using Tolerado stub, you will get something very similar. But many other stuff transparently. Check the code sample below.
// NOTE: No try catch block, a RunTimeException ToleradoException is thrown if the failure // is not recoverable
// All the hassle of doing login and setting headers encapsulated in this single call
// ToleradoStub is a ready to use stub, with no changes required
ToleradoPartnerStub pStub = new ToleradoPartnerStub(new Credential("userName@user.com", "password"));
//Binding created transparently from the given salesforce user name
//password.
//You transparently got the
//1. Fault recovery mechanism
//2. Cached stub (if its second call via the same login)
//3. QueryResult is same class as before, so no change on your rest of the
// logic.
QueryResult qr = pStub.query("select FirstName, LastName from Contact");
// ...
// process the results within QueryResult
// ...
Sample 2 : Making Partner queryMore Calls
Using queryMore requires some setting of headers to stubs for batch size and using a string query locator handle correctly.
First we will show the normal code without Tolerado framework
QueryResult qr = null;
_QueryOptions qo = new _QueryOptions();
qo.setBatchSize(250);
binding.setHeader(new SforceServiceLocator().getServiceName().getNamespaceURI(),
"QueryOptions", qo);
try {
qr = binding.query("Select name From lead");
boolean done = false;
if (qr.getSize() > 0){
while (!done) {
for(sObject lead : qr.getRecords()) {
System.out.println(lead.get_any()[0].getValue());
}
if (qr.isDone()) {
done = true;
} else {
qr = binding.queryMore(qr.getQueryLocator());
}
}
}
else {
System.out.println("No records found.");
}
System.out.println("\nQuery succesfully executed.");
}
catch (RemoteException ex) {
// No recovery from remote errors
System.out.println("\nFailed to execute query successfully, error message was: \n" +
ex.getMessage());
}
Now we will show the Tolerado simplified code sample
// Cached, Recoverable Stub
ToleradoPartnerStub pStub = new ToleradoPartnerStub(new Credential("username", "password"));
// Wrapper class for making queryMore calls super easy
// Just pass the SOQL and batch size here, it will take care of the rest
ToleradoQuery q = new ToleradoQuery(pStub, "Select name From lead",
250);
// Do Java style iteration over the ToleradoQuery
while (q.hasMoreRecords()) {
// Correct query locator used internally
SObject[] records = q.getRecords();
if (records == null || records.length == 0) break;
for(sObject lead : records) {
System.out.println(lead.get_any()[0].getValue());
}
log.debug("Fetched next " + records.length + " records !");
}
// No try catch block as run time exception is thrown, if the stub can't recover
// the error.
Sample 3: Working with SObject – Creating new Contact record
Developers need to deal with MessageElement and Sobjects while creating new Sobjects. As shown below
SObject[] cons = new SObject[1];
MessageElement[] contact = new MessageElement[5];
contact[0] = new MessageElement(new QName("FirstName"),"Joe");
contact[1] = new MessageElement(new QName("LastName"),"Blow");
contact[2] = new MessageElement(new QName("Salutation"),"Mr.");
contact[3] = new MessageElement(new QName("Phone"),"999.999.9999");
contact[4] = new MessageElement(new QName("Title"),"Purchasing Director");
cons[0] = new SObject();
cons[0].setType("Contact");
cons[0].set_any(contact);
SaveResult[] sr = null;
try {
sr = binding.create(cons);
} catch (Exception ex) {
System.out.println("An unexpected error has occurred." + ex.getMessage());
return;
}
The Tolerado code, is much simpler and more readable
ToleradoSobject sobj = new ToleradoSobject("Contact");
sobj.setAttribute("FirstName", "Joe");
sobj.setAttribute("LastName", "Blow");
sobj.setAttribute("Salutation", "Mr.");
sobj.setAttribute("Phone", "999.999.9999");
sobj.setAttribute("Title", "Purchasing Director");
// Get the updated Sobejct
SObject updatedSObject = sobj.getUpdatedSObject();
SaveResult[] saveResults = partnerStub.create(new SObject[] { updatedSObject });
What advantage you get is clearly visible
References
For more info on “Tolerado”, please follow these pointers
Tolerado for Apache Axis
Tolerado for SFDC – WSC API
Leave a Reply