opsgenie / opsgenie-integration

Apache License 2.0
28 stars 55 forks source link

Service Cloud integration is not "bulkified" #47

Closed cgb-76 closed 4 years ago

cgb-76 commented 5 years ago

Hey,

I'm struggling a bit with the implementation of the APEX trigger in the Service Cloud integration. https://github.com/opsgenie/opsgenie-integration/blob/master/salesForceServiceCloud/opsgenieTrigger.apxt

Salesforce best practice for triggers is to "bulkify" them, that is, write them to expect from 1 - 200 records at once. See: Best Practice: Bulkify Your Code.

OpsGenie's implementation only addresses Trigger.new[0] - the first record in a set that could possibly contain 200 cases. With this implementation, the rest of the records would be ignored and not sent to OpsGenie.

Possible solutions:

Wrap the existing implementation in a loop.

for(Case cse : Trigger.new)
{
    Case obj = cse;
    string id=obj.Id;
    // etc...
    opsgenieClass.xRESTCall(endpoint, payload);
}

The major problem with this is the HTTP callout at the end, which would be executed up to 200 times dependent on the number of cases passed into the trigger. The first issue is simply the amount of time this would take to process. The second issue is that a single APEX transaction can make a maximum of 100 callouts, whereas the trigger could accept up to 200 records. Hitting the callout limit would cause the entire insert/update transaction to fail and rollback. See: Callout Limits and Limitations

"Bulkify" your REST endpoint.

// create a list to hold our payloads
List<String> payloads = new List<String>();

// iterate over the cases
for(Case cse : Trigger.new)
{
    Case obj = cse;
    string id=obj.Id;
    // etc...

    string payload= '{'+
    // etc...
    '}';

    // add the payload to the list
    payloads.add(payload);
}

// combine the payloads into a single string
String combinedPayload = '[' + String.join(payloads, ',') + ']';

// now a single call, outside the loop
opsgenieClass.xRESTCall(newEndpoint, combinedPayload);

This is the best option. Leave the current endpoint as is, so existing implementations don't break. Create a new endpoint that accepts a JSON array so that Salesforce can pass up to 200 payloads in a single call.

cglrkn commented 4 years ago

Thanks for the suggestion. We decide not to use bulk actions for now but we will consider this as a feature request.