Triggers

Overview

Each JetStream service will react to certain events and execute user-supplied scripts. The server accepts a --trigger-dir command line parameter, which should point to a directory containing the trigger scripts.

The name of the trigger script file must correspond exactly to the name of the event. For example, if the JetStream service was started with --trigger-dir set to /var/lib/jetstream/triggers, JetStream would look for and execute script /var/lib/jetstream/triggers/recv.transferComplete once a transfer has been completely received. On Windows, each trigger script must have a .bat extension.

Tip

A trigger script must be an executable file.

On Linux and macOS, make sure to set the executable bit on each trigger script (e.g. with chmod).

On Windows, make sure each trigger has a .bat extension.

Tip

Including the --trigger-log command line parameter will log additional information about triggers.

Each trigger script will be passed predefined parameters, depending on which event occurred.

Event Triggers

launch

Required file name: launch

Triggered when the server successfully launches and begins listening on the control port.

Parameters:
  1. port: The control port used by the JetStream server.
#!/bin/sh
echo "JetStream server Launched on port "$1 >> log.txt

Tip

You can using this trigger to handle startup configuration, like adding destinations:

#!/bin/sh
export JETSTREAM_API_PASSWORD=secret
/usr/local/bin/jetstream api --user <username> createDestination --destinationAddress <destination_address> --sendRateMax=100000

send.destinationCreated

Required file name: send.destinationCreated

Triggered on a successful createDestination() API call.

Parameters:
  1. destination: The address and port of the new destination, in the format <ip>:<port>.
  2. sender: The address and port of the sender that created the destination, in the format <ip>:<port>.
#!/bin/sh
echo "Sender "$2" created destination "$1 >> log.txt

send.destinationDeleted

Required file name: send.destinationDeleted

Triggered on successful deleteDestination() API call.

Parameters:
  1. destination: The address and port of the deleted destination, in the format <ip>:<port>.
  2. sender: The address and port of the sender that deleted the destination, in the format <ip>:<port>.
#!/bin/sh
echo "Sender "$2" deleted destination "$1 >> log.txt

recv.transferComplete

Required file name: recv.transferComplete

Triggered when a transfer is done and files have been written to disk.

Parameters:
  1. transfer_id: A transfer ID. Transfer IDs are returned from createTransfer(), and used in other methods to refer to a specific transfer.
  2. username: User that was used to authorize the transfer.

Changed in version 1.5.0: - Removed sandbox_path parameter.

Changed in version 1.7.0: - Removed destination_directory, transfer_index, transfer_count, truncated_file_count parameters. - Added username parameter.

#!/bin/sh
echo "Transfer ID ${1} initiated by ${2} is complete." >> log.txt

Transfer File List

In addition to its input parameters, the recv.transferComplete trigger also has access to the list of files in the completed transfer, and the path of the files on disk. These are provided in stdin. The file list is presented as absolute paths to where the files were written (see Where Do Transfers Go?). This can be used for further operations on the files.

#!/bin/sh
while IFS="   " read -r manifest_file file_path || [ -n "${manifest_file}" ]; do
  echo manifest file: ${manifest_file}, file path: ${file_path} >> log.txt
done

recv.transferComplete.json

Required file name: recv.transferComplete.json

Triggered when a transfer is done and files have been written to disk.

Parameters:
  1. transfer_id: A transfer ID. Transfer IDs are returned from createTransfer(), and used in other methods to refer to a specific transfer.
  2. username: User that was used to authorize the transfer.

Changed in version 2.3.0: - Trigger added

Transfer Meta Data

The recv.transferComplete.json trigger is an alternative to the recv.transferComplete trigger that includes additional meta data about transfers in JSON format provided in stdin.

The JSON object contains the following keys:

  • inputFiles: (list) A list of file name written to disk, as seen by the sender. These paths are not sandboxed so may not be the absolute path on disk.
  • outputFiles: (list) A list of file name written to disk. These are the absolute file names after sandboxing has been applied.
  • userData: (dict) The user data set in createTransfer().

Note

The userData dictionary only includes user data included at the time of transfer creation (createTransfer()), and not user data added later using updateObjectUserData().

#!/usr/bin/env python
import json
import os.path
import sys

log = os.path.join(os.path.dirname(__file__), 'log.txt')

transferId, userName = sys.argv[1:]
data = json.load(sys.stdin)
with open(log, 'a') as stream:
    stream.write('Transfer: {!r}\n'.format(transferId))
    stream.write('UserName: {!r}\n'.format(userName))
    stream.write('Input Files: {!r}\n'.format(data['inputFiles']))
    stream.write('Output Files: {!r}\n'.format(data['outputFiles']))
    stream.write('User Data: {!r}\n'.format(data['userData']))

Tip

Naturally, trigger scripts that need to act on the received files should have access to the file system used by the receiver server.

recv.transferStarted

Required file name: recv.transferStarted

Triggered when a transfer has started to be received.

Parameters:
  1. transfer_id: A transfer ID. Transfer IDs are returned from createTransfer(), and used in other methods to refer to a specific transfer.
  2. username: User that was used to authorize the transfer.

Changed in version 2.5.1: - Trigger added

This trigger includes the same Transfer Meta Data as the recv.transferComplete.json trigger.

API Command Triggers

If the --trigger-on-api command line parameter was specified, then a trigger is called after each API command is processed. The names of these triggers are on.command, where command is the API command. For example, you may provide a trigger named on.send.createTransfer which will be called after the server processes the send.createTransfer API command.

Four parameters are provided to an API command trigger:

  1. command: (dict) The command structure submitted to the server. This is a dictionary in JSON format.
  2. status: (string) A string describing status of the command. If the command succeeded, this will be “success”.
  3. message: (string) A message returned from the server. Generally this is simply a confirmation that it has done as asked.
  4. result: (dict) The full result structure from the command. This is a dictionary in JSON format.

Since the command and result parameters are offered as dictionaries in JSON format, it may be beneficial to process an API command trigger using a Python script, rather than bash.

#!/usr/bin/env python
import json
import os.path
import sys

log = os.path.join(os.path.dirname(__file__), 'log.txt')

command, status, message, result = sys.argv[1:]
command = json.loads(command)
result = json.loads(result)
with open(log, 'a') as stream:
    stream.write('Message: {!r}\n'.format(message))
    stream.write('Status: {!r}\n'.format(status))
    stream.write('Command: {!r}\n'.format(command))
    stream.write('Result: {!r}\n'.format(result))
Message: 'Manifest requested.'
Status: 'success'
Command: {u'request': u'send.createManifest', u'parameters': {u'fileMappings': {u'/src/foo.txt': u'/dst/bar.txt'}}}
Result: {u'status': u'pending', u'processing': True, u'manifestId': u'ebec4994ea77a55c0100000000000022',
u'totalFiles': None, u'totalSize': None, u'errorMessage': None}

Trigger Considerations

There are some important details of the trigger execution model of which trigger authors should be aware:

  • Execution is serial. A long-running trigger script will block further trigger scripts from running until it is complete, at which point the other trigger scripts will be run one by one. If a trigger never exits, it will block all further triggers.
  • Execution is asynchronous. Each trigger will be called some time after the triggering event occurred. Not only does JetStream not wait for the trigger to complete, it doesn’t even wait for the trigger to start before moving on to the next task.
  • Execution is silent. No errors are reported from triggers, and output is suppressed. JetStream does not log trigger script failures or crashes. You may find it useful to do your own custom logging from within the trigger script. Specifying the --trigger-log command line parameter will add some information about which triggers are being executed, and may print the output of a trigger in some cases, although this output will not be included in a log file if one was specified using the --log command line option.