Executor Service

The Executor service provides a flexible and efficient mechanism for automating tasks and workflows within a system. It consists of two main properties: Trigger and Target, which allows you to define when and what actions to execute.

Trigger

The Trigger property defines the conditions under which the Executor service initiates an action. It specifies the event type and condition that must be met for the action to be triggered.

You can configure the following three types of triggers to execute the user defined tasks.

  1. Event based trigger

In this trigger, you can specify the type of event that initiates it (e.g., Tailor DB data update and StateFlow creation) and outline the specific conditions or criteria for its execution.

Currently, the only supported events are tailordb.type_record.created , tailordb.type_record.updated, tailordb.type_record.deleted, stateflow.state.created, stateflow.state.transitioned, stateflow.state_flow.created and stateflow.state_flow.deleted.

  1. Incoming webhook trigger

You can configure your API endpoint (webhook URL) for receiving incoming data.

  1. Schedule based trigger

This trigger can schedule tasks at specified intervals.

Target

The Target property defines the action to be executed when the Trigger condition is met. You can describe the specific task or operation to be performed, such as querying Tailor DB, sending notifications, or triggering workflows. There are two types of targets:

  1. #TargetTailorGraphql

This involves interaction with the Tailor DB and performs operations such as querying data or making changes (mutations).

  1. #TargetWebhook

With this type of target, you can send a HTTP request from your executor service. Currently we only support POST method.

Each Trigger can be configured with the above two target types, providing six ways to configure them.

Below is a sample of the Executor service manifest file.

package executor

import (
	"github.com/tailor-platform/tailorctl/schema/v2/executor"
	"tailor.build/template/manifest/services/pipeline:settings"
)

executor.#Spec & {
	Executors: [
		#eventBasedExecutor,
		#slackNotification,
		#incomingWebhookBasedExecutor,
		#scheduledEventBasedExecutor,
	]
}

Examples

Below you can find examples of three types of Trigger.

Event based trigger

Trigger with target type #TargetTailorGraphql

#eventBasedExecutor: executor.#Executor & {
	Name:        "eventbased-executor"
	Description: "Create a data based on the event"
	Trigger: executor.#TriggerEvent & {
		EventType: "tailordb.type_record.created"
		Condition: common.#Script & {
			Expr: """
				args.NamespaceName == "\(environment.#app.namespace)" && args.TypeName == "PurchaseOrder"
				"""
		}
	}
	Target: executor.#TargetTailorGraphql & {
		AppName: environment.#app.namespace
		Invoker: settings.adminInvoker
		Query: """
			mutation ($input: createPutAwayWithEventInput!) {
				createPutAwayWithEvent(input: $input)
			}"""
		Variables: common.#Script & {
			Expr: """
			({
				input: {
					"quantity": args.data.newRecord.quantity,
					"purchaseOrderID": args.data.newRecord.id,
					"putAwayDate": args.data.newRecord.purchaseOrderDate
				}
			})"""
		}
	}
}

Trigger with target type #TargetWebhook

#slackNotification: executor.#Executor & {
	Name:        "slacknotification"
	Description: "notify slack when new product is created"
	Trigger: executor.#TriggerEvent & {
		EventType: "tailordb.type_record.created"
		Condition: common.#Script & {
			Expr: """
				args.NamespaceName == "\(environment.#app.namespace)" && args.TypeName == "Product"
				"""
		}
	}
	Target: executor.#TargetWebhook & {
		URL: common.#Script & {
			Expr: "\"https://hooks.slack.com/services/{service-name}/\""
		}
		Headers: [
			{
				Key:   "Content-type"
				Value: "application/json"
			}
		]
		Body: common.#Script & {
			Expr: """
			({
				"text": "New Product Registration :tada:",
				"blocks": [
					{
						"type": "section",
						"text": {
							"type": "mrkdwn",
							"text": "*New Product Registration* :tada: " + args.data.newRecord.name
						}
					}
				]
			})"""
		}
	}
}
  • Name: The name of the executor. The name field has the validation rule ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$, and it does not allow capital letters.
  • Description: The description of the executor.
  • Trigger: The type of trigger ex: #TriggerEvent.
    • EventType: The type of event ex: tailordb.type_record.created
    • Condition: The condition for the job to get executed.
  • Target:
    • TargetTailorGraphql
      • AppName: The name of the app.
      • Query: The query to be executed.
      • Variables: The input variables for the query.
      • Invoker: The user role may be required to execute the query.
    • TargetWebhook
      • URL: The URL of the API endpoint.
      • Body:The payload or message to be included in the request.
      • Headers:
        • Key: The key in a request header.
        • Value: The value for a request header key. In the Value, you can leverage secret manager.
      • Secret: Secret is the key to generate tailor-signature-256 signature in your header. You need to use secret manager to store the secret key.
        • VaultName: The name of the vault.
        • SecretKey: The key that stores the secret.

Schedule based trigger

scheduledEventBasedExecutor: executor.#Executor & {
	Name:         "name"
	Description:  "description"
	Trigger: executor.#TriggerSchedule & {
		Timezone:  "UTC"
		Frequency: "* * * * *"
	}
	Target: executor.#TargetWebhook & {
		URL: common.#Script & {
			Expr: "\"http://localhost\""
		}
		Secret: secretmanager.#SecretValue & {
			VaultName: "vault"
			SecretKey: "key"
		}
	}
}
  • Name: The name of the executor. The name field has the validation rule ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$, and it does not allow capital letters.
  • Description: The description of the executor.
  • Trigger: The type of trigger ex: #TriggerSchedule.
    • Timezone: This refers to the specific time zone in which the job's scheduled times are interpreted and executed.
    • Frequency: The intervals at which the job is scheduled to run.
  • Target:
    • URL: The URL of the API endpoint.
    • Body:The payload or message to be included in the request.
    • Secret: Secret is the key to generate tailor-signature-256 signature in your header. You need to use secret manager to store the secret key.
      • VaultName: The name of the vault.
      • SecretKey: The key that stores the secret.

Incoming webhook trigger

incomingWebhookBasedExecutor: executor.#Executor & {
	Name:    "executor-01"
	Trigger: executor.#TriggerIncomingWebhook
	Target: executor.#TargetWebhook & {
		URL: common.#Script & {
			Expr: "\"http://localhost\""
		}
	}
}
  • Name: The name of the executor. The name field has the validation rule ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$, and it does not allow capital letters.
  • Description: The description of the executor.
  • Trigger: The type of trigger ex: #TriggerIncomingWebhook.
  • Target:
    • URL: The URL of the API endpoint.
    • Headers:
      • Key: The key in the request header.
      • Value: The value for the request header key.
    • Body: The input for the API endpoint.