When using httpClient to create app key and secret via Management API I get isError() even when the key is created

I need to intergrate our custom Developer Portal with Auth0 and so at app creation. So I need the Client ID and Client Secret from Auth0 integrated with the APP credentials of Apigee.

Using the JS policy I always end up in exchange.isError() Even though the key is created

var url = 'https://api.enterprise.apigee.com/v1/organizations/' + organization + '/developers/' + developerEmail + '/apps/' + productName + '/keys/create';
var headers = { 
    'Content-Type' : 'application/json',
    'Authorization' : base64Credentials
};
var payload = '{ "consumerKey": "' + key + '", "consumerSecret": "' + secret + '" }';


var request = new Request(url, 'POST', headers, payload);
var exchange = httpClient.send(request);


exchange.waitForComplete();


if (exchange.isSuccess()) {
    var response = exchange.getResponse();
    context.setVariable('response.content', response.content);
}
else if(exchange.isError()){
    context.setVariable('response.content', 'Error'); 
}

I want to have more control then the callout policy offers but it seems that the exchange object doesn't contain error information when isError() is true.

documentation on management API: App keys: Developer | Edge APIs (apigee.com)

0 3 416
3 REPLIES 3

I don't know what the problem is.

Is your app named the same thing as your product? In your URL construction, you specify "productName" where I would expect to see "appName".

Maybe use the callback mechanism for httpClient to get better insight?

  function onComplete(response, error) {
    if (response) {
      context.setVariable('example.status', response.status);
    }
    else {
      context.setVariable('example.error', 'Whoops: ' + error);
    }
  }


  var payload = JSON.stringify({
     consumerKey : key,
     consumerSecret : secret
  });
  var headers = {
        'Accept' : 'application/json',
        'Content-Type' : 'application/json',
        'Authorization' : 'Basic xyz'
      };
  var url = 'https://api.enterprise.apigee.com/v1/organizations/' + organization + '/developers/' + developerEmail + '/apps/' + productName + '/keys/create'

  var req = new Request(url, 'POST', headers, payload);


  httpClient.send(req, onComplete);


productName should be appName. Thanks for catching that!

The value was correct so moving on 🙂

Tried this piece of code (also from other awnsers) and it isnt working for me.

I get a fault string back:

{
    "fault": {
        "faultstring": "Execution of managementapi_app_keysecret failed with error: Javascript runtime exceeded limit of 200ms",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Do I need to configure the callback somewhere to get it working?

Google is your friend!

You're seeing a timeout. The Javascript policy is time-limited. This is done to prevent long-running JavaScript code, logic errors, and so on.

There is a timeLimit attribute available on the toplevel Javascript element. It is a value expressed in milliseconds. For example,

<Javascript timeLimit="200" name="JS-InvokeMgmtServer">
    <ResourceURL>jsc://invokeMgmtServer.js</ResourceURL>
</Javascript>
 

The default timeLimit, the value Apigee uses when no attribute is present, is 200. While this limit is sufficient for most JS tasks like reformatting messages, transforming payloads, parsing strings, and so on, it may not be sufficient when you invoke a remote service, such as the management server. If the remote service doesn't respond within 200ms, the JS policy will timeout.

You can use a larger value to allow more time for the policy. Try 2200ms.

But, be careful: there is no guarantee that all transactions will respond within 2200ms. You will need to have some mechanism to handle the failure case.