Create Callback Actions¶
Introduction¶
The seal-operator-notifier service listens for notifications at the NATS message broker. The environment key NOTIFICATION_CALLBACKS specifies for which message types the service executes callback actions. Callback URLs are the only supported callback action.
The value of NOTIFICATION_CALLBACKS is a JSON string containing an array of callback actions for every message type of interest.
Hint - reliability
If a callback cannot be executed, it is retried later. For details, refer to Handle Failing Callback Actions.
Create a Callback Action¶
Hint - using Consul
The following example describes the creation of a callback action via SEAL Operator CLI. Due to the complex nature of the NOTIFICATION_CALLBACKS key, it might be better to use Consul instead. In Consul, the key is specified here. If the key does not exist yet, you have to create it:
dc/home/env/service/operator-notifier/tag/any/NOTIFICATION_CALLBACKS
-
Open a command prompt.
-
Export the complete configuration of SEAL Operator from Consul to a YAML file. This ensures that you edit the current configuration.
operator config export <filename>.yml --insecure -
Edit the exported file
<filename>.yml. -
In the
envsection, specify the keyNOTIFICATION_CALLBACKSfor theseal-operator-notifierservice in theoperator-notifiersection:... env: service: operator-notifier: tag: any: NOTIFICATION_CALLBACKS: | { "UPDATE_TASK": [ { "action": "https://external.example.com/" } ] } ... -
Save the
<filename>.ymlfile. -
Re-import the file to Consul.
operator config import <filename>.yml --insecure -
Check the imported value for
NOTIFICATION_CALLBACKS:operator config get NOTIFICATION_CALLBACKS --service operator-notifier --insecure
Action Parameters¶
Every action has the following parameters:
Mandatory¶
-
action: stringMandatory, contains the callback URI. If the protocol is a valid URL protocol like
httporhttps, the callback URI is used as URL and aPOSTrequest is sent by default. To use another HTTP request method likeGET,PUTorPATCH, also set themethodparameter. If the request method is notGET, the notification message is sent as request body. The URL can contain placeholders that are replaced by message parameters. Placeholders use the Mustache syntax with three curly braces, for example{{{parameters.status}}}. Three curly braces insert the value without HTML escaping. For information on which message parameters are available, refer to Structure of Notification Messages.For an example using the
GETmethod, refer to Configuration Examples.
Optional¶
-
entireItem: booleanfalse: Default. Only essential message data and changed object data are sent. Essential message data includes, for example,scope,source, andsub.true: The entire object is sent, for example the complete task or document.Hint
Many message types, like
UPDATE_TASK,UPDATE_DOCUMENT, contain only essential message data and changed parameters of the object. If all parameters of the object should be sent or if unchanged object parameters have to be used in placeholders,entireItemhas to be set totrue. -
key: stringA specific parameter key that has to be contained in the data object, for example
status. Only in combination with thevalueparameter. -
value: stringSpecific parameter value that has to be set as value for the specified
keyparameter. Can be a regular expression, for example.*p402.*. -
method: stringHTTP request method to be used, default:
POST. -
headers: JSON objectAdditional HTTP headers to be sent with the request. The header values can contain placeholders that are replaced by message parameters.
Message Types¶
The supported message types are:
-
ADD_TASK -
UPDATE_TASK -
REMOVE_TASK -
UPDATE_DOCUMENT
Configuration Examples¶
Example - for every UPDATE_TASK event a POST request is sent to an external URL
{
"UPDATE_TASK": [
{
"action": "https://external.example.com/"
}
]
}
Example - for every UPDATE_TASK event a POST request with additional headers is sent to an external URL
{
"UPDATE_TASK": [
{
"action": "https://external.example.com/",
"headers": {
"My-Header1": "Foo",
"My-Header2": "{{{parameters.status}}}"
}
}
]
}
Example - depending on the task status in an UPDATE_TASK event a POST request is sent to a specific external URL
{
"UPDATE_TASK": [
{
"key": "status",
"value": "processing",
"action": "https://external.example.com/running"
},
{
"key": "status",
"value": "completed",
"action": "https://external.example.com/success"
},
{
"key": "status",
"value": "failed",
"action": "https://external.example.com/error",
"entireItem": true
}
]
}
Only in case of a failed task the usage of entireItem causes the entire task data to be sent.
Example - callback action using the GET method and placeholders
{
"UPDATE_TASK": [
{
"key": "status",
"value": ".*",
"action": "https://external.example.com/update?status={{{parameters.status}}}&taskId={{{scope}}}&userId={{{sub}}}",
"method": "GET"
}
]
}
Example - callback action if a task for a printer starting with hplaser is added
{
"ADD_TASK": [
{
"key": "metadata.Printer",
"value": "hplaser.*",
"action": "https://external.example.com/notify"
}
]
}
For a complete list of parameters included in an ADD_TASK notification message, refer to the examples in the Structure of Notification Messages section.
Structure of Notification Messages¶
The structure of a notification message looks like this.
{
source: '<service name>',
type: '<message type>',
scope: '<object ID within the Operator>',
sub: '<user ID = subject in JWT>',
parameters: {
'<key-value pairs depending on the message type>'
}
}
Example - ADD_TASK notification message
{
type: 'ADD_TASK',
scope: 'b2dab4b2-cf47-4499-9320-610d6118f2e4',
source: 'operator-p4',
sub: 'ea5f9786-04e5-4a3d-b4f1-d4544e400f6d',
parameters: {
metadata: {
Capabilities: { Color: true, Format: true, Duplex: true, TrayFormats: { oneOf: [] } },
Printer: 'hp402-3011@Ouoi',
Duplex: 'NONE',
Quality: 'NORMAL',
Color: 'gray',
Copies: 1,
Format: 'undefined',
dirty: ['dirty'],
PLS_FOLD_TYPE: 'undefined',
PLS_PUNCH_TYPE: 'undefined',
PLS_SORT_TYPE: 'undefined',
PLS_STAPLE_TYPE: 'undefined',
PLS_SCALE_TYPE: 'undefined'
},
name: 'PLOSSYS 4',
type: 'print',
tid: 'b2dab4b2-cf47-4499-9320-610d6118f2e4',
sid: 'operator-p4',
created: 1688732877737,
status: 'open',
runtime: {},
links: { self: { href: '/v1/services/operator-p4/tasks/b2dab4b2-cf47-4499-9320-610d6118f2e4' } },
inputListLength: 1,
outputListLength: 0
}
}
Example - UPDATE_TASK notification message
{
type: 'UPDATE_TASK',
scope: 'b2dab4b2-cf47-4499-9320-610d6118f2e4',
source: 'operator-p4',
sub: 'ea5f9786-04e5-4a3d-b4f1-d4544e400f6d',
parameters: {
tid: 'b2dab4b2-cf47-4499-9320-610d6118f2e4',
status: 'failed',
finished: 1688733087807
}
}
Handle Failing Callback Actions¶
If a callback action fails, for example because of a network or callback server outage, the callback action is postponed for 30 seconds and then executed again. Within these 30 seconds other waiting callback actions are executed. This is done until the callback action finally succeeds. This default behavior is adjustable by these environment variables:
MESSAGES_MAX_RETRIES: optional, maximum number of attempts for a callback. Default:0, no maximum.MESSAGES_OBEY_SEQUENCE: optional, specifies if a failing callback blocks other callbacks until it succeeds. Default:N.MESSAGES_REQUEST_TIMEOUT: optional, time after which a callback request fails with timeout. Default:20s.MESSAGES_RETRY_INTERVAL: optional, time interval between retries of a failing callback. Default:30s.