Friday, October 25, 2013

Using AggregateResult In SalesForce



Retrieving aggregate results in Apex
In Apex, we use any aggregate function like the following way:-

First we have to declare a variable of list of Aggregate results, then the query, after that we have to use a loop and get that aggregate value.

LIST<AggregateResult> noOfEmployees = new LIST<AggregateResult> ();
noOfEmployees = [SELECT COUNT(id) noOfEmp FROM Employee__c WHERE salary__c > 25000 ];
for(AggregateResult sobj : noOfEmployees)
{   
Integer empNumber = Integer.valueOf(sobj.get('noOfEmp'));
}

Thursday, October 24, 2013

Handling SFDC Managed Package Namespace Prefix with Web Service


This post tries to cover a common night mare while developing solutions on top of Salesforce using Partner/Enterprise WSDL web services. So this post can be super helpful for developers working with following technologies with Salesforce Partner/Enterpise WSDLs.
  • Java/J2EE/Spring, .NET, PHP, Perl Clients
  • A Flex application rendered inside a Visualforce page.
  • An Adobe Air desktop application

What is this Web Service issue ?

We (developers) usually develop our Java, PHP, Flex or .NET client code to make web service calls on the development org. But once the product comes close to release, we usually create a “Managed package” for it. Once managed package is created  all the CUSTOM Sobjects, Fields, etc gets a unique “PREFIX”.
From here (after getting the “prefix”) starts the real pain, all your “web service client code” that was working fantastically stable, bursts up on the very first and every consecutive call. Only solution to this problem is the web service client code needs to add the package prefix before every Sobject and Field names. But the equation becomes complex if the same code is running across a scenario where you can work with both prefixed and un-prefixed orgs. For ex.

  • Your development org is not prefixed / un-managed. So everything is available to web service client code un-prefixed. 
  • You push/deploy code(using Eclipse/ANT) to a QA org or STAGING org for testing, that is un-managed. But this org has an org wide prefix “qaorg__”. So this will prefix everything with “qaorg__”. Lets name this org as “QA” 
  • You create a managed package with prefix “mpac__”. This package will of course get  installed to client orgs or managed package testing orgs. So here everything will get prefixed by “mpac__”. Lets name this org as “MANAGED”
  • Now your web service stack has to deal with each of these orgs. So you can get any of these prefixes i.e. “no prefix”, “org prefix” or “managed package prefix”.  

How to crack this PREFIX problem ?

A couple of solutions are possible, please suggest if you have any other ideas.
  1. Create a new release of your web service client app for each package prefix. So
    • Java guys can have some ANT build properties to release an EAR or WAR file for each package prefix. Though maintaining different versions of same application might be hard.
    • Flex/Air/PHP code, it might not be an easy solution, unless you have already TOKENIFY all your .as, .php files to have all SOQL/SObject/Fields some token like “TOKEN__” before Sobject/Field/SOQL access. So for release you can run some file string replacement tool to change tokens and create a build. But this doesn’t sounds good to even me, and it can be super buggy :)
    • I will give this solution 2/10 marks.
  2. Using Custom settings to have the package prefix
    • This custom setting will have only a single field like “prefix”
    • This custom setting will be packaged(managed) separately from the main product. So your product can depend or assume that prior installation you have the custom setting managed package installed always.
    • You web service client code will first query for this custom setting to know the right prefix for an Org. Once that prefix is queried, all SOQL, Sobject and field names should be prefixed by that.
    • I will give this solution 3/10 marks.
  3. The 9/10 marks solution: Using “describeGlobal()” call via Partner/Enterprise WSDL to figure out the prefix dynamically and using that for prefixing the SOQL & Sobject Name/Fields. This solution is elaborated in details below. Note : I didn’t gave full marks to this solution, as I want more feedback and better/dynamic ideas if any.

Using “describeGlobal()” to determine the correct package prefix !

describeGlobal() call gives you a list of available objects for an organization. So one can then iterate through this list and use describeSObjects() to obtain metadata about individual objects. So here is the recipe to fetch the correct prefix.
  1. Mark any of your custom Sobject, that is of course part of your product as TOKEN. Lets say my custom object name is “Chatter_Location__c”.
  2. Make a describeGlobal() call to get the org’s describe and then list all available Sobjects in this describe via describeSObjects().
  3. For each available Sobject in iteration try matching TOKEN value with the Sobject name.
  4. For all the 3 SFDC orgs mentioned above, we will receive Sobject names as follows on making describeGlobal() call.
    • DevOrg : Chatter_Location__c
    • QA Org : qaorg__Chatter_Location__c
    • Managed Package Org : mpac__Chatter_Location__c.
  5. On having a match sub-string the prefix, so you will get either
    • “” Empty String > Dev Org
    • “qaorg__” > QA Org
    • “mpac__” > Managed package org.
  6. So, that is it guys. Now we have correct prefix in hand. We can cache this somewhere forever(usually will not change) and prefix the SOQL + Sobject Name/Fields.
Here is the sample code that shows the same recipe as above.
// Assuming  you have the right partner/enterprise binding to make the call.
DescribeGlobalResult describeGlobal = getBinding().describeGlobal();
// Token Sobject Name, this can be any Custom Sobject name from your product.
String TOKEN_SOBJECT_NAME = "Chatter_Location__c";
// Pull the list of Sobjects from the Global Describe
DescribeGlobalSObjectResult[] describeResults = describeGlobal.getSobjects();
int indexOfToken = -1;
// This variable will have the namespace prefix
String namespsacePrefix = null;
for (DescribeGlobalSObjectResult descSobjResult : describeResults) {
    String sobjName = descSobjResult.getName();
    if (sobjName != null) {
        // Try matching each Sobject Name with the TOKEN Sobject
        indexOfToken = sobjName.indexOf(TOKEN_SOBJECT_NAME);
    }
     
    if (indexOfToken != -1) {
        // If match is success, then substring the namespace prefix
        namespsacePrefix = sobjName.substring(0, indexOfToken);
        break;
    }
}
// Here we go, the final namespace prefix is here.!!!
System.out.println(namespsacePrefix);

Have any more ideas thoughts, please share !

Wednesday, October 23, 2013

Example of a Post Install Script

Salesforce Example of a Post Install Script

The following sample post install script performs these actions on package install/upgrade. If the previous version is null, that is, the package is being installed for the first time, the script: Creates a new Account called “Newco” and verifies that it was created. Creates a new instance of the custom object Survey, called “Client Satisfaction Survey”. Sends an email message to the subscriber confirming installation of the package. If the previous version is 1.0, the script creates a new instance of Survey called “Upgrading from Version 1.0”. If the package is an upgrade, the script creates a new instance of Survey called “Sample Survey during Upgrade”. If the upgrade is being pushed, the script creates a new instance of Survey called “Sample Survey during Push”. You can test a post install script using the new testInstall method of the Test class. This method takes the following arguments. A class that implements the InstallHandler interface. A Version object that specifies the version number of the existing package. An optional Boolean value that is true if the installation is a push. The default is false. This sample shows how to test a post install script implemented in the PostInstallClass Apex class.


Tuesday, October 22, 2013

rerendering commandbutton both top and bottom one

Visualforce Page


Apex Class

Tuesday, September 10, 2013

creating SOAP fault

Force.com Custom Web Services - How to create a SOAP fault
Question:

The standard salesforce.com web services defines fault and exception code when there is an error calling the services. Can I define my own fault code and exception code when writing my custom web services? If so, can you provide some samples? Thanks a lot.

Answer:

Using Apex, you cannot explicitly create your own SOAP faults. However, SOAP faults are automatically created when an Exception is thrown. So, to create your own SOAP fault, you simply throw an Exception.

Of course, Apex doesn't allow you to throw a standard exception, so you need to create your own custom exception class to throw an exception. This isn't very hard to do. Here is very simple code to create your own exception class:

public class SOAPException extends Exception {}

That is it.

To throw the exception, you simply write:

throw new SOAPException();

Salesforce.com provides plenty of documentation on how to create the classes and throw the exceptions. The biggest thing to remember is that the custom exception class must actually have the name Exception in it. Why, I don't know, but that is the way it is.

Here is a good starting point to the documentation on custom exception classes.
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_exception.htm

Friday, August 16, 2013

A common requirement of a Salesforce application is to display date and time information. What is not so common, is how this information needs to be displayed.

Varying the format of a dateTime field inside a Visualforce page is quite straightforward. It involves wrapping the field in a mask and then passing the data as a parameter, like so:

Page:
<apex:outputText value="{0,date,{!dateFormat}}">
     <apex:param value="{!myDateTime}" />
</apex:outputText>

In order to illustrate how this works, I have constructed a page and controller with a few samples. Below is a screenshot of the page displaying a single date (31st December 2010, 23:59:59) in various different formats. The first column of the table shows the string used as the date format mask, whilst the second column shows how that date appears when the mask is applied to the date.


Note that for formats that include literal text, escape characters are required in the controller so that the result renders properly. In my example, Day of the year has to be written as \'Day of the year\' in the formatting String. For all those interested, here is the page and controller code I used to construct the page:

Controller:
public class DateFormattingController {

  Datetime myDateTime = datetime.newInstance(2010, 12, 31, 23, 59, 59);

  List<String> dateFormats = new List<String> {
     'dd.MM.yy HH:mm:ss',
     'MMM-dd-yyyy hh:mm a',
     'EEEEE dd MMMMM yyyy G',
     'E hh:mm:ss:SSS z',
     'zzzzz (Z), \'Day of the year:\' D' 
  };
   
  public DateTime getMyDateTime(){
    return myDateTime;
  }

  public List<String> getDateFormats(){
    return dateFormats;
  }
}

Page:
<apex:page controller="DateFormattingController">
    
    <apex:sectionHeader title="Date Formatting"/>
    
    <apex:outputText value="Standard Output Format: {!myDateTime}"/>
    
    <apex:pageBlock >
        <apex:pageBlockTable value="{!dateFormats}" var="dateFormat">
            <apex:column headerValue="Date Format" value="{!dateFormat}"                                   width="50%"/>
            <apex:column headerValue="Output" width="50%">
                <apex:outputText value="{0,date,{!dateFormat}}">
                    <apex:param value="{!myDateTime}" />
                </apex:outputText>
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
    
</apex:page>

See Paul's Salesforce Blog for the full date format letter table. Any missing formats or unsure how to construct a particular format, leave me a comment on the post and I'll see what I can do!

Tuesday, August 13, 2013


Saleforce HTTP callouts limit workaround

I need to do tons of requests to an external service that, unfortunately, doesn't allow me to put multiple action requests within one single HTTP request, so that each action I want to send to this external service I have to do an HTTP request. Problem: Salesforce allows you to do only ten HTTP requests per execution. I could use Batch Jobs to schedule all the requests I need, but Batch Jobs are executed when resources are free, and I want to have the requests to be sent almost in real time, not "when Salesforce has time to do it".

So, here's the workaround. The key is that the limit is "per execution", and an AJAX call (done through a standard Visualforce <apex:actionFunction>) is actually a single execution. I can "loop" in Javascript to do requests as long as I need it.

Let's have a look at the code.

The controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public with sharing class testJavascript {
 public String requestStatus { get; set; }
 public String requestMore { get; set; }
 public Integer requestNumber { get; set; }
 public Integer requestCurrent { get; set; }
 public testJavascript () {
  requestStatus = '';
  requestMore = '';
  requestNumber = 10000;
  requestCurrent = 0
 }
 public void doRequest () {
  if (requestCurrent <= requestNumber) {
   Http http = new Http();
   for (Integer startPoint = requestCurrent; (requestCurrent <= requestNumber) && ((requestCurrent - startPoint) < 10); requestCurrent++) {
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://www.google.com');
        req.setMethod('GET');
    HTTPResponse res = http.send(req);
   }
   requestStatus = requestCurrent + ' out of ' + requestNumber + ' processed';
  }
  if (requestCurrent >= requestNumber)
   requestMore = 'false';
  else requestMore = 'true';
 }
}
1
 
The page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<apex:page controller="testJavascript">
<apex:form>
 <apex:outputpanel id="status">
  Status:
 
  {!requestStatus}
  <script>requestContinue = {!requestMore};</script>
 </apex:outputpanel>
 <script>
  function requestMore() {
   if (requestContinue)
    doRequest();
  }
 </script>
 <button onclick="if (doRequest()) return false; else return false;">Start</button>
 <apex:actionfunction action="{!doRequest}" name="doRequest" oncomplete="requestMore()" rerender="status">
</apex:actionfunction></apex:form>

Some explication:

  1. In the controller I have a request counter (requestCurrent, set to 0 at beginning) and a request amount (requestNumber, set to 10000 at beginning) and a method, doRequest(), that, given those two variables, executes the next 10 HTTP requests (increasing the counter) and updates the status String (requestStatus) and the requestMore String/Boolean, setting it to true if other requests are needed (if the counter is lower than the request amount we need) or false if not.
  2. In the page I have an <apex:actionFunction> pointing to this method, that rerenders the status panel. In the panel I show the status string and I update a Javascript global variable (requestContinue) with the String/Boolean given in requestMore by the doRequest() APEX method.
  3. The actionFunction has an oncomplete attribute that calls another Javascript function, requestMore(), that is in the page code. This function checks for requestContinue value (updated after each rerender): if true calls again the doRequest() actionFunction and 10 more requests are executed, if false it does nothing.
The user has just to push the <button> (that does the first actionFunction call) to start the loop.

Nice, isn't it? :-)

Tuesday, June 11, 2013

In Salesforce, if you are trying to perform a Web Service Callout in a test class, you will get an error. For example:

  1. public String sendHttpRequest(String endpointUrl, String method, DOM.Document body) {
  2.   ...
  3.   HttpRequest req = new HttpRequest();
  4.   req.setEndpoint(endpointUrl);
  5.   req.setMethod(method);
  6.   req.setBody(bodyStr);

  7.   Http http = new Http();
  8.   HttpResponse res = http.send(req);

  9.   return res.getBody();
  10. }

When your test class runs untill line #9, it will stop the entire test process by throwing the following error:

System.TypeException: Methods defined as TestMethod do not support Web service callouts, test skipped callout

What if the overall test coverage is still under 75%? This will become a roadblock for your deployment. Below is the workaround you can consider:

  1. public String sendHttpRequest(String endpointUrl, String method, DOM.Document body, Boolean isTest) {
  2.   ...
  3.   HttpRequest req = new HttpRequest();
  4.   req.setEndpoint(endpointUrl);
  5.   req.setMethod(method);
  6.   req.setBody(bodyStr);

  7.   Http http = new Http();
  8.   if(isTest) {
  9.     HttpResponse res = http.send(req);
  10.     return res.getBody()
  11.   } else {
  12.     // You can prepare some simulated data for your test class here
  13.     return simulatedData;
  14.   }
  15. }

By doing this, you can write different execution as below:

  • Actual Process:
    • You can call the sendHttpRequest method and set the isTest parameter to false.
      • sendHttpRequest(‘your endpoint’, get, ‘http request body’, false);
  • Test Process:
    • In the test process, all you need to do is just set isTest to true.
      • sendHttpRequest(‘your endpoint’, get, ‘http request body’, true);
-->

Friday, June 7, 2013

Testing HTTP Callouts with Static Data in Winter ’13

One of the most eagerly awaited Winter ’13 features, at least for developers, has been the ability to test Apex callouts. You can now test HTTP callouts by either

In this blog entry, I’ll focus on the static resource case. As an example, let’s assume that I’m retrieving JSON Account data from an external service. Here’s a simple callout that retrieves JSON account data, parses it, and returns the resulting list of accounts:

public class CalloutAccounts {
    public static List<Account> getAccounts() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://api.example.com/accounts');
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        String jsonData = res.getBody();
        List<Account> accounts =
            (List<Account>)JSON.deserialize(jsonData, List<Account>.class);
        return accounts;
    }
}

To test this callout, first, I’ll need to create a file, accounts.json, on my local machine containing test data:

[
  {
    "Name": "sForceTest1",
    "Website": "http://www.sforcetest1.com"
  },
  {
    "Name": "sForceTest2",
    "Website": "http://www.sforcetest2.com"
  },
  {
    "Name": "sForceTest3",
    "Website": "http://www.sforcetest3.com"
  }
]

Now I go to Setup | Develop | Static Resources, click New Static Resource, enter the name jsonAccounts, and select accounts.json for upload. Notice that Force.com set the MIME type based on the extension of the file I uploaded:

Now to define my test method. I’ll use StaticResourceCalloutMock to provide my Account test data when the getAccounts method executes its callout. First, I need to create an instance of StaticResourceCalloutMock and set the static resource, status code and content type header:

StaticResourceCalloutMock mock = new StaticResourceCalloutMock(); 
mock.setStaticResource('jsonAccounts');
mock.setStatusCode(200);
mock.setHeader('Content-Type', 'application/json');

Now I use Test.setMock to tell the Apex runtime I want to use this instance:

Test.setMock(HttpCalloutMock.class, mock);

Then I can test getAccounts:

Test.startTest();
List<Account> accounts = CalloutAccounts.getAccounts();
Test.stopTest();

And verify I received the expected data:

System.assertEquals(3, accounts.size()); 
System.assertEquals('sForceTest1', accounts[0].Name);
System.assertEquals('sForceTest2', accounts[1].Name);
System.assertEquals('sForceTest3', accounts[2].Name);

So, putting it all together into a test method in a test class:

@isTest
private class CalloutAccountsTest {
    @isTest static void testCallout() {
        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
        mock.setStaticResource('jsonAccounts');
        mock.setStatusCode(200);
        mock.setHeader('Content-Type', 'application/json');

        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, mock);

        // Call the method that performs the callout
        Test.startTest();
        List accounts = CalloutAccounts.getAccounts();
        Test.stopTest();

        // Verify response received contains values returned by
        // the mock response.
        System.assertEquals(3, accounts.size());
        System.assertEquals('sForceTest1', accounts[0].Name);
        System.assertEquals('sForceTest2', accounts[1].Name);
        System.assertEquals('sForceTest3', accounts[2].Name);
    }
}

In more elaborate scenarios, I might execute several callouts in a single method. For example, let’s assume I have created a file of JSON-formatted Contact data and uploaded it as the static resource jsonContacts. The method I want to test will retrieve Account data as before, then retrieve the Contacts, and go on to do some processing of the combined Account and Contact data:

public class ProcessAccountsContacts {
    public static String getJSON(String url) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res.getBody();
    }

    public static Integer processAccountsContacts() {
        String jsonData = getJSON('http://api.example.com/accounts');
        List<Account> accounts =
            (List<Account>)JSON.deserialize(jsonData, List<Account>.class);

        jsonData = getJSON('http://api.example.com/contacts');
        List<Contact> contacts =
            (List<Contact>)JSON.deserialize(jsonData, List<Contact>.class);

        // 'Processing'
        Integer result = accounts.size() + contacts.size();
        return result;
    }
}

I’ll create an instance of MultiStaticResourceCalloutMock, configuring it to provide the appropriate static resource data depending on the URL in the callout request. Here’s the test method in its entirety:

@isTest
private class ProcessAccountsContactsTest {
    @isTest static void testCallout() {
        MultiStaticResourceCalloutMock multimock =
            new MultiStaticResourceCalloutMock();
        // 3 test accounts
        multimock.setStaticResource('http://api.example.com/accounts',
            'jsonAccounts');
        // 3 test contacts
        multimock.setStaticResource('http://api.example.com/contacts',
            'jsonContacts');
        multimock.setStatusCode(200);
        multimock.setHeader('Content-Type', 'application/json');

        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, multimock);

        // Call the method that performs the callouts
        Test.startTest();
        Integer result = ProcessAccountsContacts.processAccountsContacts();
        Test.stopTest();

        // Verify response is as expected, given the test data
        System.assertEquals(6, result);
    }
}

So, testing callouts with static data is very straightforward, but what about more complex use cases? I’ll cover the HttpCalloutMock and WebServiceMock interfaces next time out and show you how to create dynamic response data with dependencies on query parameters or the request body.


Click here to view full and original article

Thursday, May 30, 2013

To add Javascript to Standard Pagelayout in Salesforce, add a HTML Home page Component with HTML checkbox checked.


Sample Javascript:

<style type="text/css">
#popup
{
display:none;
position:absolute;
height:100px;
width:100px;
background:#E6E6FA;     
border: 2px solid black;
overflow:auto;
}
#cls
{
color:red;
text-align:right;
}
</style>

<script type="text/javascript" src="/soap/ajax/22.0/connection.js"></script>

<script src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" type="text/javascript"></script>

<script type="text/javascript">
    $(document).ready( function(){

        $(".dataCell").click(function(event){   
            $("#popup").css( {position: "absolute", top:event.pageY - 110, left: event.pageX});
            var temp = $(this).prev(".dataCell").find("a").attr("href");
            var depLink = temp.substring(1);           
            var qryString = "SELECT Description__c FROM Dependent__c where Id = '" + depLink + "'";
            sforce.connection.sessionId = getCookie('sid');
            var soql = qryString.toString();
           
            var result = sforce.connection.query(soql);   
           
            var records = result.getArray("records");
            for (var i = 0; i < records.length; i++)
            {
                var taskRecord = records[i];
                $("#cont").html(taskRecord.Description__c);
            }           
           
            showBox();
        });

        $("#cls").click(function(){
            hideBox();
        });

        function showBox()
        {
            $('#popup').fadeIn("slow");
        }
        function hideBox()
        {
            $('#popup').fadeOut("slow");
        }
    });
</script>
<div id="popup">
    <div id="cls">
    <a href="#" style="color:red;">X</a><br/>
    </div>
    <div id="cont"></div>
</div>


Output:


Wednesday, May 29, 2013

Calling External Web Services from Salesforce.com – Part III: Building an Apex class that calls your web service

Part I: Hosting your web service
Part II: Opening your web service to the internet
Part III: Building an Apex class that calls your web service

In Part I & Part II of this series, I discussed the details of hosting a web service on your computer and exposing it to the internet. If you are working in an enterprise/corporate network environment, your web service is almost always not exposed to the internet. If so, I would encourage you to also read Part I & II of this series, so you get a basic idea on how to expose your web service so that Salesforce can connect to it. In this part, we will do the fun stuff – building an Apex class that can call this web service. Before we proceed, let us revise what happens when Salesforce calls our web service -

image

1 – Our custom Apex class hosted on the Salesforce.com platform makes an outbound web service call.
2 – The call reaches our modem that forwards it to the wireless router.
3 – Since port forwarding is turned on, the router then forwards the request to our computer’s IP Address.
4 - The computer’s firewall intercepts the request, and since we opened port 80 on the firewall, lets it pass through.
5 – The IIS on the computer receives the web service request, and services it.

Now that we have the basics cleared off, let’s get into the specifics – here are step-by-step instructions on building an Apex class that calls your web service :-

  • First, we need to get the WSDL file for our web service. The WSDL(Web service definition language) file is an XML-based representation of our web service – what methods it contains, data types of method parameters, return types, and the communication protocol related details.
  • To get the WSDL, simply open a browser and navigate to your web service, passing in ?wsdl as a query string parameter. For my web service, I navigated to http://localhost/MyWebService/Service1.asmx?wsdl (if you haven’t yet hosted the web service on your computer, read Part I of this article series.
  • If your web service is hosted correctly, you should see a block of XML in your browser window. Save this as a file with .wsdl extension.
  • Next, log into Salesforce.com, and go to Setup->Develop->Apex Classes. A list of classes shows up. Here, click on the “Generate from WSDL” button.

image

image

  • On the next screen, click the “Choose File” button, and select the WSDL file you had saved previously. Click the “Parse WSDL” button to check the validity of the WSDL file.
  • Did you get an error saying “Error: Failed to parse wsdl: Found more than one wsdl:binding. WSDL with multiple binding not supported” ? Well, that happens because the WSDL file generated for an Asp.Net web service has multiple bindings.
  • Let me get into a little more detail – if you open and inspect the WSDL file, you will see a <wsdl:binding> element. The binding element defines how to use the web service with a particular protocol (e.g. http), the XML encoding, the name of the operation, input/output parameters etc. For some reason, an asp.net web service WSDL file has multiple nodes for bindings. I don’t know why it does that – both nodes appear the same to me, so I don’t see the point of repeating the same information twice. Anyway, this confuses Salesforce.com when we try to import the WSDL to create an Apex class.

image

image

  • So, we do what any good software engineer would do – remove the extra binding and proceed :). So go ahead, delete the second <wsdl:binding> node. Also remove the corresponding <wsdl:port> node that was using this binding. Try parsing the file again in Salesforce.com – this should go through without errors. When it asked for Apex class name, I used “MyWebServiceApex”.
  • Navigate to the Apex class (MyWebServiceApex), and check out the code. Specially note my notes about using the correct IP Address – I cannot stress this enough. By default, Salesforce.com uses http://localhost as the address for the web service – you need to edit that in the class to make sure it is connecting to your web service.

image 

Adding a Remote Endpoint

  • Before we run the code to call our web service, we also need to let Salesforce know that this web service could be trusted. For this, we define a “Remote Site” – go to Setup->Administration setup->Security Controls->Remote Site Settings.
  • Enter your web service address etc. here, and give it a unique name.

image

  • Now you can start testing your web service.

Testing our class via Anonymous blocks

  • Next, we will test the class we just created – launch the developer console (Setup->Developer console). Locate the “Execute” text block at the top – this is where we can put our anonymous code block.

image

  • Copy-Paste the below code into the anonymous code block -
Code Snippet
  1. MyWebServiceApex.Service1Soap s1 = new MyWebServiceApex.Service1Soap();
  2. String result;
  3. result = s1.HelloWorld();
  4. System.Debug(result);
  • When you execute the code, make sure to check the “Open Log” checkbox. This will launch your execution log file as soon as your anonymous block is executed. The piece of code here basically reaches out to the web service hosted on your computer, and invokes the “HelloWorld()” web method.

image

  • Verify the log file, and you should see the output of your “System.Debug” statement in the logs :-

image

So, these were the steps you can follow to invoke your web service from Salesforce.com. This approach has various applications – you could build an “event” mechanism so that external systems are alerted whenever something happens in Salesforce.com. Or, you could build an external logging facility that logs each and every page visit to an external database. We will explore some of the additional complexities of this process in the next post.

Calling External Web Services from Salesforce.com – Part II: Opening your web service to the internet

Part I: Hosting your web service
Part II: Opening your web service to the internet
Part III: Building an Apex class that calls your web service

I have to be honest – I did not know how to do this. Having always programmed in an enterprise environment, I never gave it a thought on hosting something that is open to the internet. Fine, everybody can’t know everything, right ? Anyways, I figured there would be others as ignorant as I am (was :)), so here’s step-by-step instructions on exposing your webservice to  the internet.

  • Disclaimer – the below description is for a specific setup – where you are on a home computer with a wireless router. Be prepared to adjust the process if your setup is different.
  • First, make sure you do this on your home computer, or a place where you have full control over the network setup, environment etc.
  • We will be using port forwarding to open up the web service hosted on the IIS on your machine to the internet. To understand what is port forwarding, start by looking at the diagram below. Your home computer is actually hosted behind a few things – firewall, modem, maybe a wireless router.
  • This ensures that nothing on the internet can directly connect to your computer. It will always have to go through the modem, and the firewall. If any malicious attempt is made, the firewall will block it. The exact details are much more sophisticated than this, but this much suffices for what we are trying to do.

image

  • This setup also affects the IP address of your computer. Open command prompt (Start->{type cmd}), and run “ipconfig”. Notice your IP Address - it will be something like 192.168.1.3. This is not a real IP address on the internet – instead, it is the “internal” IP address assigned to your computer by your modem.
  • So what is your real IP address ? Go to http://www.whatsmyip.org/ – this will show your real IP address. I found mine- it was 75.123.65.169. This again is a temporary IP address – the internet service provider can switch it at any time.

image

  • Given that the modem is our “face” to the internet, any request that comes to the IP Address 75.123.65.169 is routed to my modem. The modem may choose to either discard the request, OR, it may choose to forward the request to specific devices connected to it.
  • This is where port forwarding comes in – we basically “tell” the modem/router to forward any requests that come in from the internet on a specific port, to our computer. If we turn this on for port 80, which is used by web services, it means that any incoming web service call will be forwarded to our computer.
  • Enabling port forwarding is different for each setup, so I will walk you through what I did, and leave it to you to fill in the gaps for your particular network setup. First, I opened the administration page for my wireless router- this can be usually accessed by using the first 3 digits of your IP address + 1. For e.g., in my case, since my computer’s IP was 192.168.1.3, I opened my wireless router admin screen by visiting http://192.168.1.1 in the browser.
  • It may ask you for username/password – username is usually “admin”, you will need to know the password here – I did not know of any other way around it.
  • Once you are logged in, the screen looks like this for me:-

image

  • Next, I went to the “Advanced” tab –> “Advanced Settings” –> Port forwarding”. Here I configured it forward all HTTP requests (port 80) to my computer. This is how my setup looks like -

image

  • That’s it, all incoming HTTP requests will be forwarded to your computer now. However, we’re not done yet – these incoming requests will be blocked by your computer’s firewall. We need to open port 80 on the firewall as well.
  • Open Windows Firewall configuration - If you are on Windows 7, go to Control Panel->System & Security->Windows Firewall. From the left hand menu, choose “Allow a program or feature through Windows firewall”.

image

  • In the list of services that comes up, go to the last one (World Wide Web Services (HTTP)), and check both the private and public checkboxes.

image

  • Now we’re done – your web service is now callable from the internet.
  • To test this, visit http://www.webpagetest.org/, and put your web service URL. Your web service URL is - http://{your ip address}/MyWebService/Service1.asmx. For e.g., my web service IP address is - http://75.123.65.169/MyWebService/Service1.asmx.
  • So there you go, your web service should now be accessible from the internet. It is also now ready to be called by Salesforce. In my next post, we will go over the basics of calling this web service from Salesforce.com.

Calling External Web Services from Salesforce.com Part I: Hosting your web service

Part I: Hosting your web service
Part II: Opening your web service to the internet
Part III: Building an Apex class that calls your web service

The other day, I read about the ability to call external web services from Salesforce.com, and decided to give it a try. I come from a Microsoft programming background, so I expected it to be simple & straightforward. I ended up jumping through hoops, and by the end of it, I had already decided to write this post to save others the trouble.

I decided to break the whole process down into four parts -
Part 1 – will focus on how to build the webservice that we will be using.
Part 2 – will focus on how to make the webservice accessible to Salesforce.com from the Internet.
Part 3 – will focus on the Apex code etc. required on the Salesforce side to call the web service.
Part 4 – will focus on advanced issues like error handling, arrays etc.

In this part, we will simply build an old-fashioned asp.net web service. Since this is a fairly routine task for any programmer worth his salt, I will keep the instructions as concise as I can. So, here goes:-

  • Launch Visual Studio – I am using Visual Studio 2008. Create a new Asp.Net web service (File->New->Project->Visual C#->Asp.Net Web Service Application). Name it “MyWebService”, and hit Ok.

image 

  • Hitting Ok should automatically generate a basic asp.net web service. In the solution explorer (View->Solution Explorer), there should already by a web service file named [Service1.asmx], and the corresponding C# code file [Service1.asmx.cs].
  • Hit F5, or go to Debug->Start Debugging from the menu to execute the web service. It should show you a page like the one below -

image

  • Next, you need to make sure that IIS is running on your machine. You can go to Start->{Type IIS in the search box}. This should launch IIS on your machine. If you don’t have it installed, you can visit this link to see how to install IIS.
  • Navigate to the IIS root folder- this is usually C:\inetpub\wwwroot. Create a new directory called “MyWebService” here. You will need administrative privileges on the machine for this.

image

  • Next, we are going to “Publish” the web service. Publishing is the process where the web service is actually “hosted” on IIS, instead of within visual studio.
  • In Solution Explorer, right-click on the project name, and select “Publish…”. In the “Publish Web” dialog box that comes up, click the ellipsis next to “Target location”, and navigate to the folder we just created.

image 
image

  • Make sure that you select the option “All project files” in the “Copy” section on the dialog box. and click “Publish”.
  • Once the publish is done, try navigating to http://localhost/MyWebService/Service1.asmx. If everything is setup correctly, this should bring up the web service page.

That wraps up our first part – creating a bare bones web service. In the next post, we will see how to expose this web service to the internet so that Salesforce.com can call it.

Tuesday, May 28, 2013

Salesforce.com and Web Service Integration

Get Response From External Website

1. Apex Class TestPing with DoPing() method

Using Ping instead of CreateandSendPackage for brevity – Just replace SOAPXMLBody string with the above and change your Username, Password and AccountID with yours.  You will need to break out over several string concatenations aka

SOAPXMLBody = SOAPXMLBody + "big long string";

2.  Immediate execution code from Salesforce System log or Eclipse

SalesForce System Log Debug Output


Debug output should look like:

3.  Final WSDL for Ping and CreateandSendPackage

Labels

visualforce page ( 13 ) apex integration ( 5 ) apex trigger ( 4 ) csv file from vf page ( 4 ) javascript ( 4 ) csv visualforce page ( 3 ) Too many ( 2 ) call out ( 2 ) integration ( 2 ) rest api ( 2 ) salesforce rest api ( 2 ) salesforce to salesforce integration ( 2 ) sfdc rest api ( 2 ) trigger ( 2 ) 15 digit to 18 digit ( 1 ) DML rows in Apex ( 1 ) Date Conversion ( 1 ) Date/Time conversion ( 1 ) Deploy ( 1 ) Objects to Future Annotated Methods ( 1 ) SFDC limits ( 1 ) Sobject to Future Annotated Methods ( 1 ) Test Class ( 1 ) TimeZone Conversion ( 1 ) Too many dml rows ( 1 ) Too many future calls ( 1 ) annotations ( 1 ) apex code ( 1 ) closed opportunities ( 1 ) commit ( 1 ) convert ( 1 ) create records ( 1 ) csv create records ( 1 ) custom setting ( 1 ) deployment ( 1 ) deployment changeset ( 1 ) disable apex class ( 1 ) disable apex trigger ( 1 ) disable in production ( 1 ) document ( 1 ) download ( 1 ) field name ( 1 ) formula fields ( 1 ) iframe ( 1 ) inactive ( 1 ) intellisense ( 1 ) jsforce ( 1 ) limits ( 1 ) matrix report in vf page ( 1 ) multi select ( 1 ) multi select salesforce ( 1 ) multiselect ( 1 ) paypal ( 1 ) picklist ( 1 ) record type ( 1 ) rollback ( 1 ) salesforce limits ( 1 ) salesforce list ( 1 ) salesforce map ( 1 ) salesforce rest ( 1 ) salesforce set ( 1 ) salesforce1 ( 1 ) sandbox deployment ( 1 ) sfdc collection ( 1 ) sfdc list ( 1 ) sfdc map ( 1 ) sfdc rest ( 1 ) sfdc set ( 1 ) uncommitted ( 1 ) updated field ( 1 ) user ( 1 ) validation rule opportunity ( 1 ) validation rules opportunities ( 1 ) vf page ( 1 )

Ad