Troubleshooting for iApps LX

When the iApps LX block shows an ERROR state, you can troubleshoot the problem by checking the restnoded logs (/var/log/restnoded/restnoded.log) and by looking at any block error messages. You can correct the problem by updating the relevant input property. By referencing the selfLink property that is generated during the configuration process, you can reference the block to check for errors.

  1. Issue a GET command to the selfLink of the block to check the state of the block (if ERROR) and any related messages.

Example of iApps LX Error State:

{
    "id": "61a90c30-1d8a-4d62-b79c-0b7f26d53dc4",
    "name": "hello-world-iapp-2",
    "inputProperties": [
        {
            "id": "Hello",
            "type": "STRING",
            "value": "iApp World",
            "metaData": { }
        }
    ],
    "configurationProcessorReference": {
        "link": "https://localhost/mgmt/shared/iapp/processors/hello-world-js"
    },
    "configProcessorTimeoutSeconds": 30,
    "statsProcessorTimeoutSeconds": 15,
    "state": "ERROR",
    "error": "java.net.ProtocolException: status:500, body:{"code":500,"message":"Property \"Hello\" must have a non-default value!","referer":"restnoded","originalRequestBody":"<------TRUNCATED------->",
    "generation": 1,
    "lastUpdateMicros": 1441926475902547,
    "kind": "shared:iapp:blocks:blockstate",
    "selfLink": "https://localhost/mgmt/shared/iapp/blocks/61a90c30-1d8a-4d62-b79c-0b7f26d53dc4"
}

In this example, the error message identifies that the inputProperty “value” (“iAppWorld”) which is a default value was not accepted as only non-default values are accepted.

  1. Send a PUT request, to the selfLink, with the corrected iApps LX block inputProperty values.

For example, the inputProperty “value” has been changed:

Example of the Corrected iApps LX Block:

{
   "id": "61a90c30-1d8a-4d62-b79c-0b7f26d53dc4",
   "name": "hello-world-iapp-2",
   "inputProperties": [
       {
           "id": "Hello",
           "type": "STRING",
           "value": "Foobar",
           "metaData": { }
       }
   ],
   "configurationProcessorReference": {
       "link": "https://localhost/mgmt/shared/iapp/processors/hello-world-js"
   },
   "configProcessorTimeoutSeconds": 30,
   "statsProcessorTimeoutSeconds": 15,
   "state": "BINDING",
   "generation": 1,
   "lastUpdateMicros": 1441926475902547,
   "kind": "shared:iapp:blocks:blockstate",
   "selfLink": "https://localhost/mgmt/shared/iapp/blocks/61a90c30-1d8a-4d62-b79c-0b7f26d53dc4"
}
Results:The iApps LX block instance no longer shows an ERROR state or an error message and is successfully processed with a state of BINDING.

Configuring log generation

In addition to the basic default logging that is generated when an iApps LX framework starts-up to show its availability, you can configure cusomized log generations for an entire block or for specific objects, as shown in the following examples. Within the configTaskState property, you can define this.logger.info to capture logs for the entire block. Alternatively, to capture logs for a specific object, you can identify a specific object, such as, configTaskUtil.sendPatchToBoundState. The logs are generated to the restnoded logs (/var/log/restnoded/restnoded.log).

Example of Log Generation for an iApps LX Block: In this example, by identifying the configTaskState, you can generate a log for the entire iApps LX block configuration .. code:

HelloWorldConfigProcessor.prototype.onPost = function(restOperation) {
  var configTaskState;
  try {
      configTaskState = configTaskUtil.getAndValidateConfigTaskState(restOperation);
      this.logger.info("configTaskState: ", configTaskState);
  } catch (ex) {
      restOperation.fail(ex);
      return;
  }
  this.completeRequest(restOperation, this.wellKnownPorts.STATUS_ACCEPTED);

Example of Log Generation for an iApps LX Object: In this example, a request is being sent to another URI (this.restRequestSender.send(restOp).then(function(response)) and the response can be success or error. In this example, an error response is shown (configTaskUtil.sendPatchToErrorState(configTaskState, err, referer, auth)

this.restRequestSender.send(restOp).then(function(response) {
      configTaskUtil.sendPatchToBoundState(configTaskState, referer, auth);
  }).catch (function(err) {
      configTaskUtil.sendPatchToErrorState(configTaskState, err, referer, auth);
  }).done();