-
Notifications
You must be signed in to change notification settings - Fork 2
Home
Workflows and Tasks in conductor are JSON objects with properties specifying the name, input parameters, etc. These properties are referenced across different workflows and it can become hard to maintain the correctness of these definitions when updating Workflow properties. Any issues with Workflow definitions will be reported at Workflow registration time, but not while building the definition itself.
This library attempts to solve the problem by representing Workflows and Tasks as C# classes and using builders to bind their inputs and outputs.
Workflows are built by inheriting the Workflow
abstract generic class and overriding the BuildDefinition
method. This method should make use of the WorkflowDefinitionBuilder
to programatically build up the Workflow definition. The class is parameterized with the Workflow input, Workflow output and the concrete Workflow class (see example below).
In some cases (when dealing with legacy workflows, or in cases where the builder does not yet support a specific feature of conductor) the definition can be read from a file, or by overriding the GetDefinition
method. This approach should be used as a last resort since it does not provide any compile time error checks.
Workflows are made up of Tasks, these can be SubWorkflows (other Workflows defined on Conductor), simple worker Tasks, and system Tasks. Adding tasks to Workflows is done by adding properties to the concrete Workflow class and using those as inputs for the AddTask
method of the WorkflowDefinitionBuilder
. These properties must be of type supported by one of the Builders defined. Builders are added by creating extensions for the WorkflowDefinitionBuilder
class, the library provides the most commonly used ones, but new ones can be added.
public class SendCustomerNotificationInput : WorkflowInput<SendCustomerNotificationOutput>
{
public int CustomerId { get; set; }
}
public class SendCustomerNotificationOutput : WorkflowOutput
{
public dynamic EmailBody { get; set; }
}
[Version(3)]
[OriginalName("NOTIFICATION_send_to_customer")]
public class SendCustomerNotification : Workflow<SendCustomerNotification, SendCustomerNotificationInput, SendCustomerNotificationOutput>
{
public SendCustomerNotification(
WorkflowDefinitionBuilder<SendCustomerNotification, SendCustomerNotificationInput, SendCustomerNotificationOutput> builder
) : base(builder) { }
public GetCustomerHandler GetCustomer { get; set; }
public EmailPrepareV1 PrepareEmail { get; set; }
public override void BuildDefinition()
{
_builder.AddTask(a => a.GetCustomer, b => new() { CustomerId = b.WorkflowInput.CustomerId });
_builder.AddTask(a => a.PrepareEmail, b => new() { Address = b.GetCustomer.Output.Address, Name = b.GetCustomer.Output.Name });
}
}
Without builder:
{
"createTime": 0,
"updateTime": 0,
"name": "NOTIFICATION_send_to_customer",
"description": "{\"description\":null,\"labels\":null}",
"version": 3,
"tasks": [
{
"name": "CUSTOMER_get",
"taskReferenceName": "get_customer",
"description": "{\"description\":null}",
"inputParameters": {
"customer_id": "${workflow.input.customer_id}"
},
"type": "SIMPLE",
"startDelay": 0
},
{
"name": "EMAIL_prepare",
"taskReferenceName": "prepare_email",
"description": "{\"description\":null}",
"inputParameters": {
"address": "${get_customer.output.address}",
"name": "${get_customer.output.name}"
},
"type": "SIMPLE",
"startDelay": 0
}
],
"inputParameters": [
"{\"customer_id\":{\"value\":\"\",\"description\":\" (optional)\"}}"
],
"schemaVersion": 2,
"restartable": true,
"workflowStatusListenerEnabled": true,
"timeoutSeconds": 0
}
As previously mentioned to add a task you must define property of certain type and then use AddTask extension method. For each task type there is a corresponding AddTask extension method.
Following table lists supported task types
Task model | Conductor task type | Comment |
---|---|---|
DecisionTaskModel | DECISION | |
SimpleTaskModel<TInput, TOutput> | SIMPLE | TInput is task input type, TOutput is task output type |
SubWorkflowTaskModel<TInput, TOutput> | SUB_WORKFLOW | TInput is task input type, TOutput is task output type |
TerminateTaskModel | TERMINATE | |
SwitchTaskModel | SWITCH | |
DynamicForkJoinTaskModel | DYNAMIC_FORK_JOIN,JOIN | Generates DYNAMIC_FORK_JOIN followed by JOIN |
LambdaTaskModel<TInput, TOutput> | LAMBDA | TInput is task input type, TOutput is task output type |