4

Can any one please help me solving this,

The below trigger will create an guid(random_string) and it will be passed to an controller and from controller i'm hitting the Post the data to our URL. Which working fine, But when I submitted for "Force.com Security Scanner Results". I'm getting an error.

Query: Async Future Method Inside Loops It is critical to write your Apex code to efficiently handle bulk, that is, many records at a time. This is also true for asynchronous Apex methods (those annotated with the @future keyword). Even though Apex written within an asynchronous method gets its own independent set of higher governor limits, it still has governor limits with respect to the number of @future invocations allowed in a single Apex transaction. References: http://wiki.developerforce.com/index.php/Apex_Code_Best_Practices http://wiki.developerforce.com/index.php/Governors_in_Apex_Code Async Future Method Inside Loops result path 1:

Path Id: 1674181361 Object: sendrequest in file: triggers\setAppKey.trigger L 13:
App_keygenrt.sendRequest(dac.App_Key__c,dac.Name); Object: sendrequest in file: classes\App_keygenrt.cls L 3: public static void sendRequest(String app_key,String app_name){

Trigger code

trigger setAppKey on app__c (before insert, after insert) {
    if (Trigger.isBefore){
        For (app__c dac: Trigger.new){
            Blob b = Crypto.GenerateAESKey(128);
            String h = EncodingUtil.ConvertTohex(b);
            String appkey = h.SubString(0,8)+ '-' + h.SubString(8,12) + '-' + h.SubString(12,16) + '-' + h.SubString(16,20) + '-' + h.substring(20);
            system.debug(appkey);
            dac.App_Key__c = appkey;
        }
    }
    if (Trigger.isAfter){
        For (app__c dac: Trigger.new){
         App_keygenrt.sendRequest(dac.App_Key__c,dac.Name);
        }
    }
}

Controller

public class App_keygenrt {   
        @future
        public static void sendRequest(String app_key,String app_name){
            demoTestWSCallouts call = new demoTestWSCallouts();
            if (!System.Test.isRunningTest()) {
                  call.invokeWS(app_key,app_name);
            }
        }     
}

Controller for Posting data

public class demoTestWSCallouts {   
   public HttpResponse invokeWS(String app_key,String app_name) {
      String Org_ID = UserInfo.getOrganizationId();
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http(); 
        req.setMethod('GET' ); // Method Type
        req.setEndpoint('https://------------'); // Server Url
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded'); // Content Type
        req.setBody('app_key=' + EncodingUtil.urlEncode(app_key, 'UTF-8') + '&app_name=' + EncodingUtil.urlEncode(app_name, 'UTF-8')+ '&Org_ID=' + EncodingUtil.urlEncode(Org_ID, 'UTF-8')); // Request Parameters
        req.setCompressed(true);        
        res = http.send(req);
        System.assertEquals(200, res.getStatusCode());
        return res;
        }
}

1 Answer 1

4

When a trigger executes each invocation may have up to 200 records. So, if 200 or more app__c records were updated in a single transaction the following loop would run 200 times for the first invocation of the trigger.

if (Trigger.isAfter){
    For (app__c dac: Trigger.new){
     App_keygenrt.sendRequest(dac.App_Key__c,dac.Name);
    }
}

That's 200 asynchronous calls being made to your future method, that will each result in a single callout.

Instead, build up a collection of all the requests that need to be made and pass it off in a single call to the future method.

Now the problems becomes passing the data the the HTTP Callout. In the ideal world the web service would be modified to work on multiple records at once.

If that isn't possible, you will need to work within the Callout Limits and Limitations.

2
  • Daniel Ballinger, Thanks for helping. You mean I need to add req.setTimeout(2000); in my controller
    – Chandu
    Feb 17, 2016 at 7:35
  • Increasing the timeout will certainly be part of the modifications required. The other part is that you can't make up to the potential 200 callouts in the future method. You will need to either bulkify the callouts so they can process multiple records at once or build a queuing object and use a batch job to make the API callouts. Feb 17, 2016 at 7:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .