0

I am new in salesforce and i have a REST request callout to retrieve the information from the other ORG. My problem is, I don't know if my code is correct since there is no error but in my VFPage, there's nothing displayed. Here is my code:

public with sharing class ClientController{
public String Response { get; set;}
public List<ConsoleWrapClientInfo> Responses{get;set;}
/*End point Url to web service callout*/
    private final static String ENP_POINT_URL = 'https://login.salesforce.com/services/oauth2/token';
    //For development and production https://login.salesforce.com/services/oauth2/token
    //And for sandbox https://test.salesforce.com/services/oauth2/token
    private final static String REQUEST_BODY = 'grant_type=password&client_id=clientId&client_secret=secret&username=username&password=Password';
    private final static String USERNAME = 'UserName';
    private final static String PASSWORD = 'Password';
    private final static String CONSUMER_KEY = '';
    private final static String CONSUMER_SECRET = '';
//The username, password, consumerkey and secret are given but I deleted it for security purposes
/*public ClientController()
{
Response=fetchData('GET');
}*/
     public class deserializeResponse
    {
        public String client_id;
        public String access_token;
    }
private static OAuth getAccessToken(){
        try{
            HttpRequest req = new HttpRequest();
            req.setEndpoint(ENP_POINT_URL);
            req.setMethod('POST');          
            Blob headerValue = Blob.valueOf(USERNAME + ':' + PASSWORD);
            String authorizationHeader = 'BASIC ' +
            EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader); 
            req.setBody(String.format(REQUEST_BODY ,new string[]{CONSUMER_KEY,CONSUMER_SECRET,
                                                                 USERNAME,PASSWORD}));
            req.setTimeout(60000);
            Http http = new Http();
            HttpResponse res = http.send(req);
            OAuth objAuthenticationInfo = (OAuth)JSON.deserialize(res.getbody(), OAuth.class);
            return objAuthenticationInfo;
        }catch(CallOutException ce){
            throw ce;
        }

    }

    /*To get Access token property*/
    public static OAuth authenticationDetail{
        get{
            if(authenticationDetail == null){
                authenticationDetail = getAccessToken();
            }
            return authenticationDetail;
        }set;
    }

    /*To get aouthentication detail Wrapper*/
    public class OAuth{
        public String id{get;set;}
        public String issued_at{get;set;}
        public String instance_url{get;set;}
        public String signature{get;set;}
        public String access_token{get;set;}    
    }   

public List<ConsoleWrapClientInfo> Responses()
{
     if(authenticationDetail == null){
                authenticationDetail = getAccessToken();
            Http h=new Http();
            HttpRequest req=new HttpRequest();
            req.setEndpoint('https://ap4.salesforce.com/services/apexrest/api/PackageLicense');
            req.setHeader('Authorization','Bearer '+''+authenticationDetail);
            req.setMethod('GET');
            HTTPResponse httpResponse = h.send(req);
            //this.result = httpResponse.getBody(); 
            system.debug('httpResponse.getBody() ->'+httpResponse.getBody());
            //queryReturnResponseWrapper QRRW = new queryReturnResponseWrapper();
            //QRRW = (queryReturnResponseWrapper)System.Json.deserialize(response, queryReturnResponseWrapper.class);
        //   Responses = new List<ConsoleWrapClientInfo>();
    if(httpResponse.getstatusCode() == 200 && httpResponse.getbody() != null){
    //system.debug(json.deserializeUntyped(httpResponse.getBody()));
List<ConsoleWrapClientInfo> Responses=(List<ConsoleWrapClientInfo>)json.deserialize(httpResponse.getbody(),List<ConsoleWrapClientInfo>.class);

//ConsoleWrapperList=(List<consolewrap>)json.deserialize(res.getbody(),List<consolewrap>.class);
}
     }
return Responses;
}

    @future(callout=true)
    public static void getQueryResult(){

        if(authenticationDetail != null){
            Http h=new Http();
            HttpRequest req=new HttpRequest();
            req.setEndpoint('https://ap4.salesforce.com/services/apexrest/api/PackageLicense');
            req.setHeader('Authorization','OAuth '+UserInfo.getSessionID());
            req.setMethod('POST');
            HTTPResponse httpResponse = h.send(req);
            //this.result = httpResponse.getBody(); 
            system.debug('httpResponse.getBody() ->'+httpResponse.getBody());
            //queryReturnResponseWrapper QRRW = new queryReturnResponseWrapper();
            //QRRW = (queryReturnResponseWrapper)System.Json.deserialize(response, queryReturnResponseWrapper.class);
            deserializeResponse resp2 = (deserializeResponse)JSON.deserialize(httpResponse.getbody(),deserializeResponse.class);
            Client_Org_Information__c a = [SELECT client_id__c, username__c FROM Client_Org_Information__c WHERE username__c = :USERNAME];
            //a.username__c = resp2.username__c;
            upsert a;
        }

    }

}

My VFPage:

<apex:page controller="ClientController" title="JSON Table" >

<apex:form >

    <apex:pageBlock ><h1><center>Client Org Packages</center></h1>

<apex:pageBlockTable value="{!Responses}" var="wrap">

<apex:column headerValue="Id" value="{!wrap.Id}"/>

<apex:column headerValue="NameSpace Prefix" value="{!wrap.NamespacePrefix}"/>

<apex:column headerValue="Status" value="{!wrap.Status}"/>

<apex:column headerValue="Created Date" value="{!wrap.CreatedDate}"/>

<apex:column headerValue="Last Modified Date" value="{!wrap.LastModifiedDate}"/> 

<apex:column headerValue="Name" value="{!wrap.Name}"/> 

<apex:column headerValue="Version" value="{!wrap.Version}"/> 

</apex:pageBlockTable>

</apex:pageBlock>

</apex:form>

</apex:page>

This is my batch class:

global class MonitoringBatch implements Database.Batchable<sObject>,Database.AllowsCallouts{
    global final List<Id> Infos = new List<Id>();

    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        return DataBase.getQueryLocator([SELECT client_id__c FROM Client_Org_Information__c WHERE Id IN: Infos]);
        //return MainAcounts;
    }
    global void execute(Database.BatchableContext BC,List<sObject> scope)
    {        for (Integer i=0;i<scope.size();i++){
            //scopeAcc.get(i).Commercial_Area__c=ownerMap.get(scopeAcc.get(i).OwnerId).Commercial_Area__c;
            ClientController.getQueryResult();
        }
    }
    global void finish(Database.BatchableContext BC)
    {
}
}

And my scheduled Batch to send request everynight at 10pm:

global with sharing class CallOutRequestBatchJobSchedule implements Schedulable 
{    
    public static String sched = '0 0 22 * * ?';  //Every 10:00pm 

    global static String CallOutRequestBatchJobSchedule() {
        CallOutRequestBatchJobSchedule SC = new CallOutRequestBatchJobSchedule(); 
        return System.schedule('My batch Job', sched, SC);
    }

    global void execute(SchedulableContext sc){

      MonitoringBatch bns = new MonitoringBatch();
          Database.executeBatch(bns,100);
 }
}

Hoping anyone can help me... Thanks!!!

1

From what I see, when the page is opened nothing gets executed because it's commented out:

/*
public ClientController()
{
    Response=fetchData('GET');
}
*/ 

I don't see any action parameters on your page either. So how do you expect to see something if your code does not invoke it.

Also, you have two getters for Responses

public List<ConsoleWrapClientInfo> Responses{get;set;}

public List<ConsoleWrapClientInfo> Responses()
{
     if(authenticationDetail == null)
      {
      ....
      }
}

Which one gets called is a question. You need to have one getter per property.

You don't need to check for authenticationDetail == null in public List<ConsoleWrapClientInfo> Responses() because it's already checked and initialized if null here:

public static OAuth authenticationDetail{
    get{
        if(authenticationDetail == null){
            authenticationDetail = getAccessToken();
        }
        return authenticationDetail;
    }set;
}

When any of your code inside the controller uses the authenticationDetail property, it's getter called automatically. It means that:

req.setHeader('Authorization','Bearer '+''+authenticationDetail);

is identical to:

req.setHeader('Authorization','Bearer '+''+ getAuthenticationDetail());

Consider adding a <apex:pageMessages id="msg"/> tad onto your page and ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, ce.getMessage())); instead of rethrowing exceptions throw ce;. If you don't catch them on the higher level, which you don't, you'll see an ugly run-time error message on your page. But if you utilize apex:pageMessages with ApexPages.addMessage your page will show a nicely formatted error, which is much better from user experience perspective at least.

Overall, you've got a bunch of spaghetti code and violation of coding best practices which would be better to refactor to something readable.

  • Thank you, but I still don't get it. I tried to apply this code /*public ClientController() { Response=fetchData('GET'); } */ I get this error: Unauthorized endpoint, please check Setup->Security->Remote site settings. endpoint = ap4.salesforce.com/services/apexrest/api/PackageLicense – Janjan Dain Aug 1 '18 at 9:40
  • 1
    Do exactly as the error suggests - add the endpoint to the Remote Site Settings – Eduard Aug 1 '18 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.