Actions

FIFO publish action

The purpose of this action is to publish to a Live Objects FIFO when a trigger is activated. FIFO publish is a routing feature without mustache templating (i.e. the entire data message or event is published in the FIFO, you can’t template it).

The API to manage FIFO is detailed in swagger.

Representation of a FIFO action
{
    "fifoName": "destinationfifo",
    "noRetention": false
}
Field Description

fifoName

Name of the FIFO that will receive the triggered message

noRetention

If true, messages published to the FIFO from this action will not be stored; they will be immediately dropped if no subscriber is consuming from the FIFO at the time the messages are published.

Example of an action policy routing all new data messages to a FIFO
{
    "name": "push data new to fifo",
    "enabled": true,
    "triggers": {
        "dataMessage": {
        "version": 1
    }
  },
    "actions": {
        "fifoPublish": [{"fifoName":"mydata"}]
    }
}
Example of an action policy sending data messages of a specific device to a FIFO without storing messages that are not consumed immediately
{
    "name": "push data new to fifo",
    "enabled": true,
    "triggers": {
        "dataMessage": {
            "version": 1,
            "filter": {
                "deviceIds": ["urn:lo:nsid:mqtt:deviceId2"]
            }
        }
    },
    "actions": {
        "fifoPublish": [{
                "fifoName": "mydata",
                "noRetention": true
            }]
    }
}

Creating a FIFO publish action will automatically create the corresponding FIFO if it does not already exist. The total number of FIFO is limited depending on your offer so you may need to remove existing action policy with FIFO publish action to create new ones.

By default, a FIFO will store messages for a few days depending on your offer. If no subscriber consumes the messages during this period, they will be dropped. However, storing messages coming from an action policy can be disabled by setting the noRetention field to true. In this case, if no subscriber is consuming from the FIFO at the time messages are published, these messages will be immediately dropped.

If the FIFO messages published from an action are not consumed for 7 consecutive days, or if the targeted FIFO has been deleted; the ActionPolicy will be disabled. Its suspension field will provide additional details.

Http Push action

The purpose of this action is to do an HTTP POST to a given URL with custom headers and a custom body. The body can be templated using the Mustache templating syntax.

Depending on the user needs, a retry policy can be enabled to be more resilient to listening endpoint downtimes.

Representation of a Http Push action
{
     "webhookUrl": String,
     "headers": Map of <String,List of String> ({"key": ["value1","value2",...]}),
     "retryOnFailure": boolean,
     "jsonPath": String,
     "content": String
}
field name is required description

webhookUrl

required

defines the location of the webhook (only the secured ports 443, 8443 and 9243 are allowed, the insecure ports ex: 80 or 8080 are not supported).

headers

optional

defines custom headers that are sent along the HTTP POST request.
This can be used to pass authorization headers or any header required to connect to an endpoint.

signingSecret

optional

Secret used to compute an HMAC signature of the HTTP POST request. The signature is added as a header for authenticity and integrity validation.
The signature header name is x-orange-hmac-sha256-signature and it is accompanied by a timestamp header named x-orange-timestamp-epoch-seconds. SigningSecret is a UTF-8 string with a length between 20 and 128 characters. See HTTP Push signature verification process.

retryOnFailure

optional

Enables retry on failure policy (see related section)

jsonPath

optional

Select a part of the triggering data using a jsonPath syntax. This selected data will be used as the root of the template datacontext. This field can be omitted when you want to work with the whole data in template.

content

optional

A string representing a Mustache template. This template will be rendered as the request body.

Example of Http Push action on a data message trigger
{
    "name": "some_user_friendly_name",
    "enabled": true,
    "triggers": {
        "dataMessage": {
        }
    },
    "actions": {
        "httpPush": [{
            "webhookUrl": "https://hooks.myservice.com/services/SOMEWEBHOOKREFERENCE",
            "headers": {"authorization": ["Bearer 00000000-0000-0000-0000-000000000000"]},
            "retryOnFailure": true,
            "content": "{\"text\": \"data pushed to stream : {{streamId}}, at {{timestamp}}\"}"
        }]
    }
}

Generated headers

x-orange-lo-policy-id

Every Http Push request contains a header with the action policy id.

If the id of an action policy is 6c95837b-251d-41d8-95f1-42facdf8e71e. The http push will have the following header:

x-orange-lo-policy-id:6c95837b-251d-41d8-95f1-42facdf8e71e
x-orange-lo-message-id

Every Http Push request contains a header with an id that identifies that push uniquely (this id will be kept across retries in case of errors). This id can be used to identify if a message has been delivered multiple times to the webhook.

x-orange-lo-message-id: 00000000-0000-0000-0000-000000000000
x-orange-timestamp-epoch-seconds

If a signingSecret is configured, this header is added with the Unix epoch timestamp (in seconds). See below for how to use it to validate the request.

x-orange-hmac-sha256-signature

If a signingSecret is configured, this header is added with an HMAC-SHA-256 signature (hex-encoded). See below for how to use it to validate the request.

x-orange-hmac-sha256-signature: 28208ff5566f18c2ae740294cf77fd683000947c64c83156969b5a45dfba4b17

Live Objects will try to validate the body of the HTTP POST as JSON object and will set the request Content-Type header accordingly:

  • application/json if the body contains valid JSON object

  • text/plain otherwise

HTTP Push signature verification process

If a signingSecret is configured, Live Objects signs the HTTP POST message using the secret key (signingSecret) and the HMAC-SHA-256 algorithm, encodes the resulting signature in hex, and includes it in the x-orange-hmac-sha256-signature header. To mitigate replay attacks, Live Objects also adds a x-orange-timestamp-epoch-seconds header.

The webhook server should validate the request by computing the signature and comparing it with the one provided in the headers using the following steps.

  1. Store the signingSecret securely on your server

  2. Gather inputs as UTF-8 strings:

    • originid = x-orange-lo-policy-id header value

    • messageuuid = x-orange-lo-message-id header value

    • epochseconds = x-orange-timestamp-epoch-seconds header value

    • requestbody = exact HTTP POST body as a string (UTF-8)

  3. Check freshness: compare epochseconds with the server’s local time; it should be within an acceptable timeframe (e.g., 3–5 minutes). Using an NTP-synchronized clock is recommended.

  4. Build the input string with colon separators, without extra spaces: epochseconds:originid:messageuuid:requestbody

  5. Compute the HMAC using HMAC-SHA-256 with signingSecret as key, then hex-encode the result.

  6. Compare the computed signature to the x-orange-hmac-sha256-signature header value. Use a constant-time comparison if possible. If they match and the timestamp is within the allowed window, the request is considered authentic and unmodified.

Example

  • epochseconds: 1710000000 (GMT: Saturday 9 March 2024 16:00:00)

  • originid: origin-123

  • messageuuid: uuid-456

  • requestbody: {"foo":"bar"}

  • signingSecret: mySecretKey

String to sign: 1710000000:origin-123:uuid-456:{"foo":"bar"}

Signature (hex): 28208ff5566f18c2ae740294cf77fd683000947c64c83156969b5a45dfba4b17

General documentation regarding webhooks and HMAC:

Policy and error management

When an error message is sent back by the destination resource, a retry policy will occur (if configured when the Http Push Action was created). The Http Push action will be retried depending on the HTTP error code sent back from the destination resource to Live Objects.

Table 1. Error handling according to HTTP ERROR
HTTP ERROR CLASS Error handling mode

4xx

Unrecoverable error: discard Http Push action

5xx

Recoverable error: retry Http Push action execution (if retryPolicy is true) otherwise discard the Http Push action execution

When enabled, the retry policy will try to regularly post a request to the resource referenced by the Http Push action url parameter. These retries will be attempted over around twenty-four hours. The retry pattern is subject to change, but it currently follows:

Table 2. Retries and delays (in order)
# of retry delay between retry

3

5 seconds

3

5 minutes

12

2 hours

In the case where the retries are unsuccessful, the Http Push action execution is discarded.

If the HttpPush error rate is too high (> 90%) for 7 consecutive days; the ActionPolicy will be disabled. Its suspension field will provide additional details.

Message Overflow

If the targeted servers for HTTP Push (webHook) are down or slow, HTTP push requests will be buffered. The buffer size, mutualized between all your HTTP Push action policies can contain up to 10.000 requests. If this limit is reached, the oldest request will be discarded first and an AuditLog will be recorded.

As a consequence, if more than 10.000 messages are waiting to be pushed to your HTTP servers, then some of them will start to be dropped. The messages pending retry are not included in this amount.

There are 2 typical cases where this can happen :

  • the HTTP server is not available, then each message needs to wait for the 5s timeout before continuing its retry cycle

  • the HTTP server has a slower response time than the rate at which messages are being pushed

If this happens, the number of pending messages will increase up to 10.000 and the overflow mechanism will be triggered.

In order to decrease the risk of congestion and overflow, HTTP Push requests are performed with some parallelism when several messages are pending (up to 10 concurrent requests).

Security considerations

A secure resource endpoint (HTTPS) should always be used. Using a non secure endpoint (HTTP) is a security issue as the data exchange between Live Objects and the resource endpoint will not be encrypted. This is especially true when leveraging the custom headers mechanisms to pass authentication token.

As a general recommendation, when using a custom authorization header, consider it insecure and be sure to give the token/credentials the least permissions. It should only be able to do an HTTP POST on the defined resource location.

Http Push Results

Each Http Push action with an ERROR will generate an audit log message. This can help analyze traffic problems.

The solution is to:

{
    "tenantId": "httppush550b5cd6-b8c6-49a4-baa9-d3c21a84202d",
    "httpPushRequest": {
        "url": "http://localhost:14567",
        "retryOnFailure": false,
        "headers": null,
        "requestBody": "{\"x\":0}",
        "messageUUID": "b5540f77-bbc8-42c8-9942-35c0b133a689"
    },
    "success": false,
    "responseStatusCode": 400,
    "responseBody": "KO",
    "errorMessage": "an error message"
}

About HTTPS certificate

When using https to push data to a webhook, the certification chain must be valid according to the default Java 8 JVM implementation. Any self signed certificate or certificate issued by an unknown organization (according to the JAVA 8 JVM) presented by a webhook will be refused and the http push action will not be executed.

About HTTP/HTTPS authorized ports and reachable IP address

  • The list of ports authorized by Live Objects during a http push action, are: 443 and 8443 (HTTPS), 80 and 8080 (HTTP), 9243 for ES. Other ports are blocked.

  • The Remote HTTP Servers or domains with IPV6 IP address are not supported by Live Objects.

If you have a 403 forbidden error, you need to check if you have using a right port number. In the other hand, the remote server must allow the port number that you are using.

HTTP_PUSH vs FIFO

Performance Security Resilience Easy to integrate Keep message sequence Recommended for

HTTP PUSH

➖ : significant protocol overhead (http headers, 200 OK responses)

➖ : retries increases the load

➖ : requires to open and secure a TCP port on the Internet to receive traffic.

➖ : buffer of 10K messages max / account, 24h of retry max

➕ : http very well known in the developers community

➕ : compatible with stateless servers

➖ : Retry policy changes significantly the sequencing of messages.

➖ : Complicates the processing of events in the customer’s IT (typically state processing)

prototypes and small applications with low quality of service constraints

MQTTs Application

➕ : messages are acked or stay in the FIFO, no need of retries

➕ : optimized protocol overhead

➕➕ : no incoming connections from the Internet to your server, only outgoing, strong authentication supported on Live Objects (TLS client certificate)

➕ : buffer (FIFO queue) for up to 7 days of message retention in the FIFOs

➖ : requires the integration of a mqtt client (less known in the web developers community). See our code samples here.

➕ : FIFO preserves the sequencing of messages, facilitates the processing of events in the client’s IT (typically state processing)

for large deployments

Azure Event Hubs action

The purpose of this action is to push a message into Azure Event Hubs service. The body can be templated using the Mustache templating syntax.

Depending on the user needs, a retry policy can be enabled to be more resilient to listening endpoint downtimes.

Error management, message overflow, rate limiting, auditlog, certificate aspects are identical to http push action.

Representation of a Azure Event Hubs action
{
	"eventHubsNamespace": "myEventHubsNamespace",
	"eventHubName":"myEventHubName",
	"sharedAccessKeyName":"mySharedAccessKeyName",
	"sharedAccessKey":"mySharedAccessKey",
	"content": "{\"temperature\": {{temp}} }",
	"jsonPath":"value",
	"retryOnFailure":false
}
field name is required description

eventHubsNamespace

required

The Event Hubs namespace where is located the targeted Event Hub.

eventHubName

required

The name of the targeted Event Hub.

sharedAccessKeyName

required

The name of the shared access policy of the targeted Event Hub.

sharedAccessKey

required

The shared access key of the shared access policy.

jsonPath

optional

The json path to extract from the considered message (or event), it will be taken as the root datacontext object when combined with a mustache template in content.

content

optional

A raw string or a mustache (https://mustache.github.io/mustache.5.html) template describing the webhook body. If empty, the raw event will be used.

retryOnFailure

required

Indicate if a retry policy should be set up in case of a delivery failure.