InfraJS Target

This event target does programatic transformations on received CloudEvents using a Javascript function.

Prerequisites

Basic knowledge of JavaScript ES5 is required. Please note there are limitations to the interpreter:

  • ES6 is not supported.
  • Regular expressions are not fully compatible with ES5 specification.
  • No imports are allowed.
  • No libraries are pre-loaded.

Create the InfraJS Target

Create an instance of the InfraJS Target at TriggerMesh as part of a Bridge.

  • Name is an internal identifier for the target.
  • JS Script is the function that contains the event manipulation.
  • Timeout is the amount of milliseconds to wait before timing out the script.
  • Type Loop Protection when enabled will raise an error if the returned CloudEvent type is the same as the incoming one.

JS Script

The JS Script field must include a function named handle with a single parameter for the incoming CloudEvent, and return the outgoing CloudEvent.

  • The incoming parameter is the JSON representation of the incoming event.
  • The incoming parameter can be re-used as the outgoing parameter. That is useful if we want to modify a small set of the values in the incoming event.
  • The outgoing event must be a JSON structure that contains context attributes at the root and data payload at the data element. See JSON format reference.
  • If the outgoing event is nil or no outgoing event is returned, no CloudEvent will be replied and the processing will be considered successful.
  • When not present at the outgoing event, these context fields will be defaulted:
  • specversion will be set to the incoming value.
  • source will be set to the incoming value.
  • id will be set to the incoming value.
  • datacontenttype will be defaulted to application/json.

Examples

These examples for the InfraJS target show different usages of the JS Script function. The incoming parameter for all of the examples will be this CloudEvent:

{
  "id": "aabb-ccdd",
  "type": "example.type",
  "source": "example.source",
  "specversion" : "1.0",
  "datacontenttype" : "application/json",
  "data": {"key1":"value1","key2":"value2", "key3": true}
}

Reply New Event

Discard the input and generate a new event. Context fields missing at the new event will be automatically filled from the input.

function handle(input) {
  nevent = {
    data: {
      "hello": "world",
      "nest": {"nested1": [1,2,3],  "nested2": "nestedvalue"}},
    "type": "test.response.type",
  };

  return nevent;
}

Values from the input event can be used when composing the reply.

function handle(input) {
  nevent = {
    data: {
      "hello": "world",
      "works": input.data.key3,
      "nest": {"nested1": [1,2,3],  "nested2": input.data.key1}},
    "type": "test.response.type",
  };

  return nevent;
}

Conditional Reply

Conditionals can be used for a range of cases. In this example the value of a field is used to decide if a reply should be emited.

function handle(input) {
  if (input.data.key3 == true) {
    return;
  }

  nevent = {
    data: {"hello": "world"},
    "type": "test.response.type",
  };

  return nevent;
}

Conditionals can also be used to set different CloudEvent types, which might be useful to route events, or bring complex logic composing the outgoing data payload.

Reply Using Incoming Event

When the output event shares structure with the incoming event, it is recommended to use the incoming parameter object as the reply.

function handle(input) {
  // modify context type
  input.type = "test.response.type";

  // add context subject field
  input.subject = "InfraJS test";

  // add extended header to context
  input.environment = "production";

  // add new data field
  input.data.key4 = Date().toString();

  // replace data field
  input.data.key3 = false;

  // modify data field
  input.data.key2 = input.data["key2"] + ".extended";

  // delete data field
  delete input.data["key1"];

  return input;
}

Using logs

Although the console object is available, the InfraJS script provides a log function that accepts a string message, and write logs in a format that can be processed along with the rest of logs produced at this target.

function handle(input) {
  if (input.type == "not.wanted.type") {
    log("we received a non wanted type!")
    return
  }

  input.type = "test.response.type"

  return input;
}

Using built-in functions

Javascript core functions (ES5) can be used. In this example we are preparing a JSON payload to be sent to the HTTP Target, which requires a stringified body element.

function handle(input) {
  body = {"search": [{"key": input.data.key1}]}

  event = {
    type: "searchservice.request",
    "data": {"body": JSON.stringify(body)}
  }

  return event
}