Execution flow details
The section goes into the details of what causes the automation to execute, the important steps of the execution flow, and what happens with the result of the automation. A simplified explanation is described here.
Implicit automation
An automation is considered implicit, if the trigger uses a before, or an after event; for example beforeCreate and afterCreate.
Implicit automation is automatically executed whenever we interact with specific resources, such as records or users.
The two variations of events (before and after) follow the same path, with the difference in when the event is dispatched, and how the resulting value is used.
before events are dispatched first and their execution result may affect the rest of the execution, while the after events are dispatched after and the execution result does not affect the rest of the execution.
@startuml actor User as u participant "Corteza component" as cc u -> cc: Perform operation for resource activate cc cc -> cc: Access control check cc -> cc: Content sanitization and validation note over cc Not all resources implement sanitization and validation. end note box "Automation system" participant "Event bus" as evtbs cc -> evtbs: Dispatch the before event activate evtbs evtbs -> evtbs: Filter for registered triggers participant "Automation" as aa evtbs -> aa: Trigger execution activate aa aa -> aa: Execute automation note over aa The automation inherits the invoking users' permissions when trying to access Corteza. end note aa -> cc: Return the execution result note over cc If the automation is asynchronous the component will not await for the automation to complete. end note deactivate aa deactivate evtbs end box cc -> cc: Process execution result note over cc Refer to the bellow description for details on how the result is handled. end note cc -> cc: Content sanitization and validation note over cc Not all resources implement sanitization and validation. === The content is again sanitized and validated as the automation may change the values. end note cc -> cc: Complete the initial operation note over cc This normally changes the data in the database, hence a destructive operation. end note cc -> evtbs: Dispatch the after event activate evtbs evtbs -> evtbs: Filter for registered triggers evtbs -> aa: Trigger execution activate aa aa -> aa: Execute automation note over aa The automation inherits the invoking users' permissions when trying to access Corteza. end note note over cc The component does not await for the after event to complete. end note deactivate aa deactivate evtbs cc -> u: Response deactivate cc @enduml
A component receives a request to interact with a resource. |
For example; we wish to create a new record, or update the email of a user. |
||
Access control checks if the invoker is allowed to perform the operation. |
If the invoker is not allowed to perform the operation, the request is rejected and no automation is executed. |
||
Content sanitization and validation prepare and validate the data. |
Before any destructive operation occurs and before the |
||
The |
If the automation is synchronous, the operation awaits for the dispatched event to resolve before continuing the initial operation. If the automation is asynchronous, the initial operation does not await. The resulting value of the synchronous automation affects how the initial operation should continue:
|
||
Content validation and sanitization occurs. |
Before any destructive operation occurs, the modified values are validated and sanitized.
If the validation fails, the request is rejected and the |
||
The resource is manipulated. |
The original operation completes and the change is permanently written to the store. |
||
The |
The operation does not await for the event to resolve and the result of the automation is therefore ignored.
|
Explicit automation
An automation is considered explicit, if the trigger uses an onManual event for any resource.
|
In some cases, you can use explicit automation to replace the need for sink routes. DevNote add some documentation regarding the above statement. |
Explicit automation is executed when manually invoked. On the front-end this is usually done with a button press, but under-the-hood, this is just an HTTP request to an API endpoint.
|
Automation scripts and workflows define separate API endpoints to invoke explicit automation. For automation script this is a For workflows this is a |
@startuml actor User as u participant "Corteza component" as cc u -> cc: Request to execute an automation activate cc cc -> cc: Find the requested automation cc -> cc: Access control note over cc Access control checks if the user is allowed to execute this automation. === This is workflow specific. end note box "Automation system" participant "Automation" as aa cc -> aa: Request to execute automation activate aa aa -> aa: Execute automation note over aa The automation inherits the invoking users' permissions when trying to access Corteza. end note aa -> cc: Return the execution result note over cc If the automation is asynchronous the component will not await for the automation to complete. end note deactivate aa end box cc -> u: Response deactivate cc @enduml
A component receives a request to execute an automation. |
For example; a CRM user pressed the button to send an email message, or to initiate an outbound phone call. |
||
(Workflow specific) The RBAC facility checks if the invoker is allowed to execute the automation. |
If the invoker is not allowed to execute the workflow, the request is rejected.
|
||
The automation is executed and the results are returned as a standard HTTP response. |
The results provide the output of the automation, along with some metadata such as execution stack traces and error messages. |
Deferred automation
An automation is considered deferred, if the trigger uses an onInterval on an onTimestamp event.
Deferred automation is invoked by the system based on the provided temporal information. The execution is not tied to an operation (such as a manual invocation or an event).
Under-the-hood, Corteza defines a ticker, that dispatches onInterval and onTimestamp events once every minute (can be configured via EVENTBUS_SCHEDULER_INTERVAL .env variable).
The dispatched events are then used to match and invoke any automation with conforming triggers.
|
Corteza dispatches interval and timestamp events for the system and compose components. Internally, these events are the same, but are kept for legacy reasons. |
|
Deferred automation requires you to explicitly set the invoking user as the automation is executed by the system and we are unable to determine the invoking user. |
@startuml participant "Scheduler" as sch activate sch note over sch The scheduler is started at boot time and terminated when the server is shut down. end note box "Automation system" participant "Event bus" as evtbs sch -> evtbs: Dispatch event in intervals note over sch The default interval is 1min, but can be configured. end note activate evtbs evtbs -> evtbs: Filter for registered triggers participant "Automation" as aa evtbs -> aa: Trigger execution activate aa aa -> aa: Execute automation deactivate aa deactivate evtbs deactivate sch end box @enduml
The system ticker dispatches an |
The events are dispatched on the eventbus. |
The automation is executed asynchronously and the results are ignored. |
The execution value of the automation does not affect any other automation. |
Sink automation
An automation is considered sink, if the trigger is bound to the System Sink resource.
A sink automation is executed when the system component receives an HTTP request to the /sink API endpoint.
The execution is not tied to an operation (such as a manual invocation or an event).
|
Sink automation requires you to explicitly set the invoking user as the automation is executed by an external user and we are unable to determine the invoking user. |
@startuml actor Unknown as u box "Corteza system component" participant "HTTP Router" as rr participant "System service" as ss activate rr activate ss u -> rr: HTTP request to /sink note over u, rr #F5D380A5 Sink requests are validated with a sink signature, not with the standard auth token. end note rr -> ss: Request to handle ss -> ss: Verify sink signature note over ss * existence, * location, * structure, * validity. end note ss -> ss: Validate request with signature note over ss The signature claims are used to validate the request and the contents. end note end box box "Automation system" participant "Event bus" as evtbs ss -> evtbs: Dispatch the onRequest event activate evtbs evtbs -> evtbs: Filter for registered triggers participant "Automation" as aa evtbs -> aa: Trigger execution activate aa aa -> aa: Execute automation aa -> ss: Return the execution result note over ss If the automation is asynchronous the component will not await for the automation to complete. end note deactivate aa deactivate evtbs end box ss -> ss: Prepare HTTP response note over ss Set headers, status, and payload. end note ss -> u: Response note over u, ss The system component bypasses the REST layer when responding to sink requests. end note deactivate ss @enduml
The system component receives an HTTP request to the |
For example; Refer to the DevOps guide/sink routes for setup details. |
||
The signature is validated |
Firstly the sink signature is validated to make sure it was not altered.
|
||
The signature is used to validate the request. |
The system validates the protocol, headers, origin, and other signature constraints. |
||
The |
If the automation is synchronous, the operation awaits for the dispatched event to resolve before continuing the initial operation. If the automation is asynchronous, the initial operation does not await. The resulting value of the synchronous automation affects how the server should respond:
|