Wednesday, May 10, 2017

Sample example for consuming Rest Web Service (RestWSSampleWithParam) containing web method with parameters from same Salesforce ORG.

Scenario: Suppose we have a rest web service in ORG1 (As posted in previous post named as "RestWSSampleWithParam"). This service has a web method (getRestSampleResponse) which contains 2 parameters. Now our aim is to call the web service from same ORG (ORF1).

Solution: Below is the apex code example for consuming rest web service from same Org.
Pre-step: Before copy paste the below code base, do the remote site setting for the endPoint URL.


/**
 * Consuming Rest Web Service (RestWSSampleWithParam) from same ORG with parameters.
 **/
public class RestWSWithParamsConsumeFromSameOrg
{
  public static void callingRestWS(){
    try {
      // Setup remote site setting for the below URL.
          String url = 'https://ap5.salesforce.com/services/apexrest/RestWSSampleParamExmpl';
          system.debug('Response URL'  +url);   
          
          HttpRequest req = new HttpRequest();
          req.setMethod('POST');
          //req.setHeader('content-type', 'application/json');
          req.setHeader('Content-Type', 'application/xml; charset=utf-8');
          req.setEndpoint(url);   
          req.setHeader('Authorization', 'OAuth '+UserInfo.getSessionId());
          req.setBody('<?xml version="1.0" encoding="UTF-8" ?><request><firstName>Arun</firstName><lastName>Hazra</lastName></request>');
    
          Http http = new Http();
          
          HTTPResponse resp = http.send(req);
          
          system.debug('Response body'  +resp.getBody()); 
          system.debug('STATUS: '+ resp.getStatus());
          system.debug('STATUS_CODE:'+ resp.getStatusCode());    
    } catch(System.CalloutException e){
      System.debug('Sorry, You have an error ' + e.getMessage());
    }
  }
}

Rest Web Service Apex Code Sample (Web Method contains parameters).

Below is a simple example of a rest web service (RestWSSampleWithParam) with a web method (getRestSampleResponse)contains parameters.

/**
 * Rest Web Service Example.
 **/
 @RestResource(urlMapping='/RestWSSampleParamExmpl/*')
global with sharing class RestWSSampleWithParam
{
  @HttpPost
  global static String getRestSampleResponse(String firstName, String lastName)
  {
    return 'Hello! ' + firstName + ' ' + lastName;
  }
}

Sample example for consuming Rest Web Service (RestWSSample) from one Salesforce ORG to another.

Scenario: Suppose we have a rest web service in ORG1 (As posted in previous post named as "RestWSSample"). Now our aim is to call the web service from different ORG (ORF2).

Solution: Below is the steps and apex code example for consuming rest web service from different Org.

ORG1 Activity:
1. Login to ORG1, where your web service is written.
2. Go to Setup > Create > Apps
3. Click on Apps will open Apps detail page. From this page click on "New" button under "Connected Apps" section.
4. In a new page enter the details.

5. Once it is saved, then in detail page it will auto create below 2 details,
i> Consumer Key,
ii> Consumer Secret

ORG2 Activity:
1. Login to ORG2, from where ORG1 web service will be called.
2. Setup remote site setting.
3. Now copy past the below apex code to call the ORG1 rest web service.


/**
 * Consuming Rest Web Service (RestWSSample) from different ORG.
 **/
public class RestWSConsumeFromDifferentOrg
{
    String endPointUrl = 'https://ap5.salesforce.com/services/apexrest/RestWSSampleExmpl';   
    
    public void callingRestWS(){
        HttpRequest req = new HttpRequest();
        string EndPt = endPointUrl;
        
        // Set request header to send token, setMethod, and set Endpoint
        req.setHeader('Authorization','Bearer '+ getAccessToken());        
        req.setMethod('GET');
        req.setEndpoint(EndPt);
        
        Http http = new Http();        
        //finally make a call
        HttpResponse res = http.send(req);
        
        system.debug('RESPONSE_BODY'+res.getbody());
    }
    
    private String getAccessToken(){
        String retVal = null;
        
        // This four variables are required for authentication to Oauth Token for ORG2 where WS is exist.
  // Consumer Key
  String consumerKey = 'Consumer Key created on ORG1 connected App' ;
        // Consumer Secret
  String consumerSecret = 'Consumer Secret created on ORG1 connected App';
        String username= 'ORG1 user name';
        String password= 'ORG1 password';
        
        //using this request body we'll make API call
        String reqbody = 'grant_type=password&client_id='+consumerKey+'&client_secret='
                        +consumerSecret+'&username='+username+'&password='+password;
    
        HttpRequest req = new HttpRequest();
        req.setBody(reqbody);
        req.setMethod('GET');
        req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
        
        Http http = new Http();
        HttpResponse res = http.send(req);
        
        OAuthWrapperClass objAuthenticationInfo = (OAuthWrapperClass)JSON.deserialize(res.getbody(), OAuthWrapperClass.class);
        
        if(objAuthenticationInfo != null && objAuthenticationInfo.access_token != null){
            retVal = objAuthenticationInfo.access_token;
        }
        
        return retVal;
    }
    
 //Wrapper class for OAuth details.
    private class OAuthWrapperClass{
        private String instance_url;
        private String access_token;
        private String Id;
        private String token_type;
        private String signature;
        private String issued_at;                
    }
}

Output: If every thing is OK, then while calling the callingRestWS() method from an anonymous window  will printing the response in debug message.

Sample example for consuming Rest Web Service (RestWSSample) from same Salesforce ORG.

Scenario: Suppose we have a rest web service in ORG1 (As posted in previous post named as "RestWSSample"). Now our aim is to call the web service from same ORG (ORF1).

Solution: Below is the apex code example for consuming rest web service from same Org.
Pre-step: Before copy paste the below code base, do the remote site setting for the endPoint URL.


/**
 * Consuming Rest Web Service (RestWSSample) from same ORG.
 **/
public class RestWSConsumeFromSameOrg
{
 public static void callingRestWS(){
  try {
   // Setup remote site setting for the below URL.
         String url = 'https://ap5.salesforce.com/services/apexrest/RestWSSampleExmpl';
         system.debug('Response URL'  +url);   
         
         HttpRequest req = new HttpRequest();
         req.setMethod('GET');
         req.setHeader('content-type', 'application/json');
         req.setEndpoint(url);   
         req.setHeader('Authorization', 'OAuth '+UserInfo.getSessionId());

         Http http = new Http();
         
         HTTPResponse resp = http.send(req);
         
         system.debug('Response body'  +resp.getBody()); 
         system.debug('STATUS: '+ resp.getStatus());
         system.debug('STATUS_CODE:'+ resp.getStatusCode());    
  } catch(System.CalloutException e){
   System.debug('Sorry, You have an error ' + e.getMessage());
  }
 }
}


Output: If every thing is OK, then while calling the callingRestWS() method from an anonymous window  will pring the debug message and for debug message 'Response body' it will display the below debug message,
"Response body Success Response."

Rest Web Service Apex Code Sample.

Generally there are 6 annotation used to expose an Apex class as a RESTful Web service.

  1. @RestResource(urlMapping='/yourUrl') ==> This should be used above class declaration. Where value of urlMapping denotes your endpoint.
  2. @HttpDelete ==>  This should be used above web method declaration.
  3. @HttpGet ==>  This should be used above web method declaration.
  4. @HttpPatch ==>  This should be used above web method declaration.
  5. @HttpPost ==>  This should be used above web method declaration.
  6. @HttpPut ==>  This should be used above web method declaration.


Scenario : Create a simple rest web service, which has a simple web method which will return a string as a response.

Solution: Below code base is a simple rest web service example in Apex.
Now for simplicity, we are simply used @HttpGet annotation for the below web method.

/**
 * Rest Web Service Example.
 **/
@RestResource(urlMapping='/RestWSSampleExmpl/*')
global with sharing class RestWSSample
{
 @HttpGet
 global static String getRestSampleResponse()
 {
  return 'Success Response.';
 }
}

Note: Apex REST supports two formats for representations of resources: JSON and XML.

Tuesday, May 9, 2017

How to create a jar file for WSDL generated from Salesforce.

1. Create your WSDL from Salesorce. Let say for this example its name is "MyWS.wsdl"
2. Download the below jars (Version can be difference),

  • antlr-runtime-3.5.jar
  • force-wsc-29.0.0.jar
  • ST4-4.0.7.jar
  • tools.jar
3. Copy paste all jars and wsdl in a folder.
4. Open command prompt and change directory to above folder location and finally run the below command,


D:\SFDC Migration>java -classpath force-wsc-29.0.0.jar;ST4-4.0.7.jar;antlr-runtime-3.5.jar;tools.jar com.sforce.ws.tools.wsdlc MyWS.wsdl MyWS.jar

It will create the jar file named as "MyWS.jar"


Saturday, May 6, 2017

How to call Salesforce SOAP service from java.

Scenario :
Suppose we have a SOAP web service in one Salesforce ORG, as mentioned in my below post (SOAP Web Service Example in Apex.). Now in this service there is a web method named as createEmployeeRecord(), containing 2 parameters,

Employee name in String format.
Employee roll number in Integer format.

This web method is responsible for Inserting employee records based on parameters passed.

Now, our aim is to call this web method from a JAVA application.

Solution :
Below are the detail steps to solve the above scenario,

To do this, we need 3 external JAR files,
a> force-wsc-29.0.0.jar (Version can be change, for this example I used V-29.0.0)
b> Jar file generated form Enterprise WSDL,
c> Jar file generated for your web-service WSDL.

Once the above Jars are ready, then crate a JAVA Project and add these jar files to in project library. Finally copy paste the below class code to call the web service method named as createEmployeeRecord().


JAVA Code Example :

import com.sforce.soap.enterprise.Connector;
import com.sforce.soap.enterprise.EnterpriseConnection;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

public class MainClass {
 static final String USERNAME = "user name of the ORG of webservice";
 static final String PASSWORD = "password";
 static EnterpriseConnection connection;

 public static void main(String[] args) {
  ConnectorConfig config = new ConnectorConfig();
  config.setUsername(USERNAME);
  config.setPassword(PASSWORD);

  try {
   System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
   connection = Connector.newConnection(config);

   com.sforce.soap.MyWebService.SoapConnection soap = com.sforce.soap.MyWebService.Connector.newConnection("",
     "");
   soap.setSessionHeader(config.getSessionId());

   System.out.println(soap.createEmployeeRecord("Jhon", 103));

  } catch (ConnectionException e1) {
   e1.printStackTrace();
  }
 }

}


NOTE:
Check my next post to know how to create a jar file from WSDL

Friday, May 5, 2017

How to call Web Services Method (SOAP) from one Salesforce ORG to another.

Scenario :
Suppose we have a SOAP web service in one Salesforce ORG (ORG 1), as mentioned in my below post. Now in this service there is a web method named as createEmployeeRecord(), containing 2 parameters,

  • Employee name in String format.
  • Employee roll number in Integer format.

This web method is responsible for Inserting employee records based on parameters passed.

Now, our aim is to call this web method from another Salesforce ORG (ORG 2).

Solution :
Below are the detail steps to solve the above scenario,

Activity in ORG 1.
1. Logged in to ORG 1.
2. Create a SOAP web service (MyWebService). To create this Web service, just check my below post and do the same.
3. Once you crate MyWebService, go to that class and click on "Generate WSDL" button. It will open a WSDL file. Just copy paste the contain and save it as "myWebService.xml"
4. Now, click on Setup and search "API" in left side search box. Then open Develop>API.
5. Click on API link will open "API WSDL" detail page, where you get a link "Generate Partner WSDL" under "Partner WSDL" section.
6. Click on this "Generate Partner WSDL" link and it will open a WSDL file. Just copy paste the contain and save it as "partner.xml".

Activity in ORG 2.
7. Logged in to ORG 2.
8. Security Controls > Remote Site Settings
9. Set up 2 new active remote sites for previously created 2 WSDL (Step 3, 5), by click on "New Remote Site" button.
10."Remote Site URL" will be found from generated xml files (Step 3, 5). Copy paste the "location" url under "soap:address" attributes of those xml. In xml it look like this,
<soap:address location="https://login.salesforce.com/services/Soap/u/39.0"/>
11.Once remote sites have been set up, go to Develop > Apex Class and click on "Generate from WSDL" button and chose the generate xml files (Step 3, 5).
12.After successful complete of step 11, system will generate some auto-generated classes for those 2 WSDL.
13.For this example, I will use the below auto-generated classes to call ORG1 web service method [createEmployeeRecord()].
14.Now create a new class as follows to call the web service method,

####################################################################

public class ConsumeWS{
    private static final String userName = 'ORG1 user name';
    private static final String password = 'ORG1 password';
    private static String sessionId = null;
   
    // Method to get the session id.
    private static String getSessionId(){      
        partnerSoapSforceCom.Soap prtnrSoapIns = new partnerSoapSforceCom.Soap();
        partnerSoapSforceCom.LoginResult rslt = prtnrSoapIns.login(userName, password);
       
        if(rslt != null)
            sessionId = rslt.sessionId;
         
        return sessionId;      
    }
   
    // Method responsible for web service method call.
    public static void callWSMethod(){
        soapSforceComSchemasClassMywebservi.MyWebService stub = new soapSforceComSchemasClassMywebservi.MyWebService();
        stub.SessionHeader = new soapSforceComSchemasClassMywebservi.SessionHeader_element();
       
        stub.SessionHeader.sessionId = getSessionId();
        System.debug('Response from web service :::::::: '+ stub.createEmployeeRecord('Mark',10));
    }
}
####################################################################
To test the scenario, open the anonymous window and call the callWSMethod() method of the above created class and it will execute result as follows,

  1. If there is no exception from service side, then it will crate a new employee record as per value passed as a parameters and in debug log it will shown "SUCCESS" message as response.
  2. If there is any exception from service side, then it will not crate any employee record and in debug log it will shown "FAILURE" message as response.

Thursday, May 4, 2017

SOAP Web Service Example in Apex.

Exposing Apex Methods as SOAP Web Services is very simple.

Scenario : Suppose we have a custom Employee Object having 2 properties Name and Roll Number.
Now we want to create a web method or web service method, which will take employee name and roll number as parameters and Insert the record in Employee Object.

Below is a simple example for the above scenario,

###############################################
global class MyWebService {

webservice static String createEmployeeRecord(String empName, Integer empRollNo){
    if(empName != null && empName.trim().length() > 0 && empRollNo != null && empRollNo > 0){
      Employee__c empIns = new Employee__c(Name__c = empName, Roll_Number__c = empRollNo);
      try{
            INSERT empIns;
      }catch(DmlException e){
            System.debug('Error while performing Employee insertion.');
            return 'FAILURE';
      }
      return 'SUCCESS';
    }else{
            return 'FAILURE';
    }
  }
}
###############################################
Considerations :

  1. Method should be define with "webservice static"
  2. Class should be declared as "global"
  3. Following elements should not be the web service method's parameters
  •          Maps
  •          Sets
  •          Pattern objects
  •          Matcher objects
  •          Exception objects

How to Sort Wrapper class Collection in Apex

Sorting of Primitive Data Types like <String> (eg. List of student names) is easy in collection.
But suppose you have a scenario like below,

  1. You have a list of employees (Wrapper Class).
  2. Say this Employee wrapper contains few primitive type like <employee name, employee id, employee salary etc.)
  3. Now the problem is that we have to sort the list of Employees based on their name.


So, for the above you can not use simple sorting mechanism. Here is the concept of wrapper class sorting.
For the same Salesforce provides us the " Comparable" INTERFACE.

Lets check the sample apex code for the above scenario.

########### Create an Employee Wrapper Class ###########

public class EmployeeWrapperEg{
    public String empName;
    public String empId;
    public Double empSalary;
}
########### Create an EmployeeComparatorEg Class which will implements Comparable Interface and hence define it's compareTo() method###########




public class EmployeeComparatorEg implements Comparable{
    public EmployeeWrapperEg emplInst;
    
    // Constructor
    public EmployeeComparatorEg(EmployeeWrapperEg emp) {
      emplInst = emp;
    }
    
    public Integer compareTo(Object compareTo){
        // Cast argument to EmployeeWrapper
        EmployeeComparatorEg compareToEmpl = (EmployeeComparatorEg)compareTo;
    
        // The return value of 0 indicates that both elements are equal.
        Integer returnValue = 0;
        
         if(emplInst.empName > compareToEmpl.emplInst.empName){
          // Set return value to a positive value.
          returnValue = 1;
        } else if(emplInst.empName < compareToEmpl.emplInst.empName){
          // Set return value to a negative value.
          returnValue = -1;
        }
        
        
        return returnValue;
    }
}
########### Finally create a client class to test the sorting  scenario ###########





public class EmployeeComparatorTestEg{
    
    /** Client method to get sorted list of employees based on their
      * Name with the help of Salesforce's Comparable Interface.
      */
    public Static List<EmployeeComparatorEg> getListOfEmpNameAsSortedOrder(){
        List<EmployeeWrapperEg> lstOfEmps = new List<EmployeeWrapperEg>();
        
        lstOfEmps = getListOfEmployee();
        System.debug('Simple list of employee::::::::::::::: '+lstOfEmps);
        
        List<EmployeeComparatorEg> lstOfSortedEmps = new List<EmployeeComparatorEg>();
        for(EmployeeWrapperEg empIns : lstOfEmps){
            lstOfSortedEmps.add(new EmployeeComparatorEg(empIns));
        }
    
        lstOfSortedEmps.sort();
        System.debug('Sorted list by name ::::::::::::::: '+lstOfSortedEmps);
        
        return lstOfSortedEmps;
    }
    
    /** Initialize list of employee wrapper. For simplicity I have make it manually.
      * It can be set from different source like database or any external system.
      */
    private static List<EmployeeWrapperEg> getListOfEmployee(){
        List<EmployeeWrapperEg> lstOfEmps = new List<EmployeeWrapperEg>();
        
        EmployeeWrapperEg epm1 = new EmployeeWrapperEg();
        epm1.empName = 'Mark';
        epm1.empId = 'E-100';
        epm1.empSalary = 10000;
        
        EmployeeWrapperEg epm2 = new EmployeeWrapperEg();
        epm2.empName = 'Jon';
        epm2.empId = 'E-102';
        epm2.empSalary = 9000;
        
        
        EmployeeWrapperEg epm3 = new EmployeeWrapperEg();
        epm3.empName = 'Luce';
        epm3.empId = 'E-101';
        epm3.empSalary = 9500;
        
        lstOfEmps.add(epm1);
        lstOfEmps.add(epm2);
        lstOfEmps.add(epm3);
        
        return lstOfEmps;
    }
}
########### From Anonymous Window call getListOfEmpNameAsSortedOrder() method of above  EmployeeComparatorTestEg class to check
the normal and sorted list of employee in debug log.###########

Execute the below line of code in Anonymous window.
EmployeeComparatorTestEg.getListOfEmpNameAsSortedOrder();


Output:

15:32:48:013 USER_DEBUG [10]|DEBUG|Simple list of employee:::::::::::::::
(EmployeeWrapperEg:[empId=E-100, empName=Mark, empSalary=10000.0],
 EmployeeWrapperEg:[empId=E-102, empName=Jon, empSalary=9000.0],
 EmployeeWrapperEg:[empId=E-101, empName=Luce, empSalary=9500.0])

15:32:48:014 USER_DEBUG [18]|DEBUG|Sorted list by name :::::::::::::::
(EmployeeComparatorEg:[emplInst=EmployeeWrapperEg:[empId=E-102, empName=Jon, empSalary=9000.0]],
 EmployeeComparatorEg:[emplInst=EmployeeWrapperEg:[empId=E-101, empName=Luce, empSalary=9500.0]],

 EmployeeComparatorEg:[emplInst=EmployeeWrapperEg:[empId=E-100, empName=Mark, empSalary=10000.0]])

LWC to LWC Communication using Lightning Messaging Service (Part - 2)

In my previous post ( previous post link ) we have learn how to create a Lightning Messaging Service with 6 steps and today we will use the ...