0

My managed package contains a custom setting and a post install script that populates data in that custom setting. The custom setting is protected. Here is the code -

global class PostInstallSetup implements InstallHandler {

  @future(callout=true)
  global static void doSetup(Id orgId, Id installerId) {
    My_Settings__c settings = My_Settings__c.getOrgDefaults();
    if (settings == null || settings.Api_Token__c == null) {
      Organization org = [Select Name, Id From Organization where id = :orgId];
      User usr = [Select name, email from User where id = :installerId];

      Http http = new Http();
      HttpRequest req = new HttpRequest(); 
      req.setMethod('POST');
      req.setEndpoint('https://myserver.com/api/apex/setup');
      SetupRequestBody reqBody = new SetupRequestBody();
      if (org != null) {
        reqBody.orgId = org.Id;
        reqBody.orgName = org.Name;
      }
      if (usr != null) {
        reqBody.contactName = usr.name;
        reqBody.contactEmail = usr.email;
      }

      req.setBody(JSON.serialize(reqBody));

      HTTPResponse res = http.send(req);
      SetupResponse parsedRes = (SetupResponse) JSON.deserialize(res.getBody(), SetupResponse.class);
      settings.Api_Token__c = parsedRes.apiToken;
      upsert settings;
    }
  }

  global void onInstall(InstallContext context) {
    doSetup(context.organizationId(), context.installerId());
  }

  private class SetupRequestBody {
      String orgId;
      String orgName;
      String contactName;
      String contactEmail;
  }

  private class SetupResponse {
    String apiToken;
  }
}

https://myserver.com is added as a remote site setting in the package. Installation happens successfully, However I don't see any API call made to my server. The test code passes successfully with 100% coverage -

@isTest
global class MyTest {

  @isTest
  static void testInstallScript() {
    Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
    PostInstallSetup postinstall = new PostInstallSetup();
    Test.testInstall(postinstall, null);
  }

  global class MockHttpResponseGenerator implements HttpCalloutMock {
      global HTTPResponse respond(HTTPRequest req) {
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"apiToken":"test"}');
        res.setStatusCode(200);
        return res;
      }
  }
}

Unfortunately, there is no way for me to debug this in customer org.

  • Are you facing issue in main class or test class? – Tushar Sharma May 17 '18 at 9:34
  • main class, which is used as post install script. Installation succeeds but it never makes the API call. Sorry fro the confusion. – vishesh May 17 '18 at 9:37
  • Can you explain why you need to do this via a web service call instead of direct Apex code? – Keith C May 17 '18 at 9:46
  • App needs to register new installation to an external service and retrieve the API key – vishesh May 17 '18 at 9:52
  • 1
    For debugging purposes, have you tried wrapping the contents of doSetup() in a try / catch, and then sending any error messages to a separate endpoint on your server? This would give you some visibility (assuming the issue isn't actually with the callout itself) to the sf logs – alphaBytes May 17 '18 at 13:41

Your Answer

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

Browse other questions tagged or ask your own question.