Skip to content

Commit 876a2d5

Browse files
Ticket ## : Start to manage the STAGE, manage human task
1 parent d8417be commit 876a2d5

27 files changed

Lines changed: 1134 additions & 299 deletions

src/CaseManagement.CMMN.Host/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) SimpleIdServer. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3-
using CaseManagement.Workflow.Domains;
3+
using CaseManagement.CMMN.Domains;
44
using Microsoft.AspNetCore.Authentication.Cookies;
55
using Microsoft.AspNetCore.Builder;
66
using Microsoft.AspNetCore.Hosting;

src/CaseManagement.CMMN/Builders/CMMNHumanTaskBuilder.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,12 @@ public CMMNHumanTaskBuilder SetFormId(string formId)
2121
cmmnTask.FormId = formId;
2222
return this;
2323
}
24+
25+
public CMMNHumanTaskBuilder SetPerformerRef(string performerRef)
26+
{
27+
var cmmnTask = (WorkflowElementDefinition as CMMNPlanItemDefinition).PlanItemDefinitionHumanTask;
28+
cmmnTask.PerformerRef = performerRef;
29+
return this;
30+
}
2431
}
2532
}

src/CaseManagement.CMMN/CaseInstance/Processors/BaseCMMNTaskProcessor.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,21 @@ public abstract class BaseCMMNTaskProcessor : ICMMNPlanItemProcessor
1010
{
1111
public abstract CMMNWorkflowElementTypes Type { get; }
1212

13-
public Task Handle(PlanItemProcessorParameter parameter, CancellationToken token)
13+
public Task<PlanItemProcessorParameter> Handle(PlanItemProcessorParameter parameter, CancellationToken token)
1414
{
15-
var cancellationTokenSource = new CancellationTokenSource();
16-
var task = new Task(() => HandleTask(parameter, cancellationTokenSource), token, TaskCreationOptions.LongRunning);
15+
var task = new Task<PlanItemProcessorParameter>(() =>
16+
{
17+
var cancellationTokenSource = new CancellationTokenSource();
18+
return HandleTask(parameter, cancellationTokenSource).Result;
19+
}, token, TaskCreationOptions.LongRunning);
1720
task.Start();
1821
return task;
1922
}
2023

2124
protected abstract Task Run(PlanItemProcessorParameter parameter, CancellationToken token);
25+
protected abstract void Unsubscribe();
2226

23-
private async void HandleTask(PlanItemProcessorParameter parameter, CancellationTokenSource tokenSource)
27+
private async Task<PlanItemProcessorParameter> HandleTask(PlanItemProcessorParameter parameter, CancellationTokenSource tokenSource)
2428
{
2529
CMMNCriterionListener.Listen(parameter);
2630
var isManuallyActivated = CMMNManualActivationListener.Listen(parameter);
@@ -33,6 +37,22 @@ private async void HandleTask(PlanItemProcessorParameter parameter, Cancellation
3337
bool isTerminate = false;
3438
bool isOperationExecuted = false;
3539
bool continueExecution = true;
40+
var parentTerminateEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentTerminate, () =>
41+
{
42+
isTerminate = true;
43+
tokenSource.Cancel();
44+
});
45+
var parentSuspendEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentSuspend, () =>
46+
{
47+
isSuspend = true;
48+
tokenSource.Cancel();
49+
});
50+
var parentResumeEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentResume, () =>
51+
{
52+
tokenSource = new CancellationTokenSource();
53+
isSuspend = false;
54+
isOperationExecuted = false;
55+
});
3656
var resumeEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.Resume, () =>
3757
{
3858
tokenSource = new CancellationTokenSource();
@@ -72,18 +92,25 @@ private async void HandleTask(PlanItemProcessorParameter parameter, Cancellation
7292
{
7393
continueExecution = false;
7494
}
95+
96+
Unsubscribe();
7597
}
7698
catch(Exception)
7799
{
78100
parameter.WorkflowInstance.MakeTransition(parameter.WorkflowElementInstance.Id, CMMNTransitions.Fault);
79101
isSuspend = true;
102+
Unsubscribe();
80103
}
81104
}
82105
}
83106

107+
parentTerminateEvtListener.Unsubscribe();
108+
parentSuspendEvtListener.Unsubscribe();
109+
parentResumeEvtListener.Unsubscribe();
84110
suspendEvtListener.Unsubscribe();
85111
terminateEvtListener.Unsubscribe();
86112
resumeEvtListener.Unsubscribe();
113+
return parameter;
87114
}
88115
}
89116
}
Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,34 @@
1-
namespace CaseManagement.CMMN.CaseInstance.Processors
1+
using CaseManagement.CMMN.CaseInstance.Processors.Listeners;
2+
using CaseManagement.CMMN.Domains;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace CaseManagement.CMMN.CaseInstance.Processors
27
{
3-
/*
48
public class CMMNHumanTaskProcessor : BaseCMMNTaskProcessor
59
{
6-
public CMMNHumanTaskProcessor(IProcessorHelper processorHelper) : base(processorHelper)
7-
{
8-
}
10+
public override CMMNWorkflowElementTypes Type => CMMNWorkflowElementTypes.HumanTask;
911

10-
public override string ProcessFlowElementType => Enum.GetName(typeof(CMMNPlanItemDefinitionTypes), CMMNPlanItemDefinitionTypes.HumanTask).ToLowerInvariant();
12+
private FormInstanceSubmittedListener _listener;
1113

12-
protected override async Task Run(WorkflowHandlerContext context, CancellationToken token)
14+
protected override Task Run(PlanItemProcessorParameter parameter, CancellationToken token)
1315
{
14-
var pf = context.ProcessFlowInstance;
15-
var cmmnPlanItem = context.GetCMMNPlanItem();
16-
var humanTask = context.GetCMMNHumanTask();
17-
var formInstance = pf.GetFormInstance(context.CurrentElement.Id);
18-
if (formInstance == null && !string.IsNullOrWhiteSpace(humanTask.FormId))
16+
var humanTask = (parameter.WorkflowInstance.GetWorkflowElementDefinition(parameter.WorkflowElementInstance.Id, parameter.WorkflowDefinition) as CMMNPlanItemDefinition).PlanItemDefinitionHumanTask;
17+
parameter.WorkflowInstance.CreateFormInstance(parameter.WorkflowElementInstance.Id, humanTask.FormId, humanTask.PerformerRef);
18+
if (humanTask.IsBlocking)
1919
{
20-
pf.CreateForm(cmmnPlanItem.Id, humanTask.FormId, humanTask.PerformerRef);
20+
_listener = CMMNFormInstanceSubmittedListener.Listen(parameter);
2121
}
2222

23-
else if (formInstance != null && formInstance.Status == FormInstanceStatus.Complete)
24-
{
25-
pf.CompletePlanItem(cmmnPlanItem);
26-
// await context.ExecuteNext(token);
27-
return;
28-
}
23+
return Task.CompletedTask;
24+
}
2925

30-
if (humanTask.IsBlocking)
26+
protected override void Unsubscribe()
27+
{
28+
if (_listener != null)
3129
{
32-
pf.BlockElement(cmmnPlanItem);
33-
return;
30+
_listener.Unsubscribe();
3431
}
35-
36-
pf.CompletePlanItem(cmmnPlanItem);
37-
return;
3832
}
3933
}
40-
*/
4134
}

src/CaseManagement.CMMN/CaseInstance/Processors/CMMNProcessTaskProcessor.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public CMMNProcessTaskProcessor(ICaseLaunchProcessCommandHandler caseLaunchProce
2323

2424
protected override async Task Run(PlanItemProcessorParameter parameter, CancellationToken token)
2525
{
26-
var planItem = parameter.WorkflowDefinition.Elements.First(p => p.Id == parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
26+
var planItem = parameter.WorkflowDefinition.GetElement(parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
2727
var processTask = planItem.PlanItemDefinitionProcessTask;
2828
if (processTask.IsBlocking)
2929
{
@@ -35,9 +35,14 @@ protected override async Task Run(PlanItemProcessorParameter parameter, Cancella
3535
}
3636
}
3737

38+
protected override void Unsubscribe()
39+
{
40+
41+
}
42+
3843
private async Task HandleProcess(PlanItemProcessorParameter parameter, CancellationToken token)
3944
{
40-
var planItem = parameter.WorkflowDefinition.Elements.First(p => p.Id == parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
45+
var planItem = parameter.WorkflowDefinition.GetElement(parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
4146
var processTask = planItem.PlanItemDefinitionProcessTask;
4247
var parameters = new Dictionary<string, string>();
4348
var processRef = processTask.ProcessRef;
@@ -79,7 +84,7 @@ await _caseLaunchProcessCommandHandler.Handle(new LaunchCaseProcessCommand(proce
7984

8085
private Task HandleLaunchCaseProcessCallback(PlanItemProcessorParameter parameter, CaseProcessResponse caseProcessResponse, CancellationToken token)
8186
{
82-
var planItem = parameter.WorkflowDefinition.Elements.First(p => p.Id == parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
87+
var planItem = parameter.WorkflowDefinition.GetElement(parameter.WorkflowElementInstance.WorkflowElementDefinitionId) as CMMNPlanItemDefinition;
8388
var processTask = planItem.PlanItemDefinitionProcessTask;
8489
foreach (var mapping in processTask.Mappings)
8590
{
@@ -99,7 +104,7 @@ private Task HandleLaunchCaseProcessCallback(PlanItemProcessorParameter paramete
99104

100105
parameter.WorkflowInstance.SetVariable(mapping.TargetRef.Name, vv);
101106
}
102-
107+
103108
parameter.WorkflowInstance.MakeTransition(parameter.WorkflowElementInstance.Id, CMMNTransitions.Complete);
104109
return Task.CompletedTask;
105110
}
Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using CaseManagement.CMMN.CaseInstance.Processors.Listeners;
22
using CaseManagement.CMMN.Domains;
3+
using System;
4+
using System.Linq;
35
using System.Threading;
46
using System.Threading.Tasks;
57

@@ -9,15 +11,15 @@ public class CMMNStageProcessor : ICMMNPlanItemProcessor
911
{
1012
public CMMNWorkflowElementTypes Type => CMMNWorkflowElementTypes.Stage;
1113

12-
public Task Handle(PlanItemProcessorParameter parameter, CancellationToken token)
14+
public Task<PlanItemProcessorParameter> Handle(PlanItemProcessorParameter parameter, CancellationToken token)
1315
{
1416
var cancellationTokenSource = new CancellationTokenSource();
15-
var task = new Task(() => HandleTask(parameter, cancellationTokenSource), token, TaskCreationOptions.LongRunning);
17+
var task = new Task<PlanItemProcessorParameter>(() => HandleTask(parameter, cancellationTokenSource), TaskCreationOptions.LongRunning);
1618
task.Start();
1719
return task;
1820
}
1921

20-
private void HandleTask(PlanItemProcessorParameter parameter, CancellationTokenSource tokenSource)
22+
private PlanItemProcessorParameter HandleTask(PlanItemProcessorParameter parameter, CancellationTokenSource tokenSource)
2123
{
2224
CMMNCriterionListener.Listen(parameter);
2325
var isManuallyActivated = CMMNManualActivationListener.Listen(parameter);
@@ -26,11 +28,100 @@ private void HandleTask(PlanItemProcessorParameter parameter, CancellationTokenS
2628
parameter.WorkflowInstance.MakeTransition(parameter.WorkflowElementInstance.Id, CMMNTransitions.Start);
2729
}
2830

31+
2932
var cmmnStageDefinition = parameter.WorkflowInstance.GetWorkflowElementDefinition(parameter.WorkflowElementInstance.Id, parameter.WorkflowDefinition) as CMMNStageDefinition;
30-
foreach(var elt in cmmnStageDefinition.Elements)
33+
foreach (var elt in cmmnStageDefinition.Elements)
3134
{
32-
parameter.WorkflowInstance.CreateWorkflowElementInstance(elt);
35+
parameter.WorkflowInstance.CreateWorkflowElementInstance(elt, parameter.WorkflowElementInstance.Id);
3336
}
37+
38+
var children = cmmnStageDefinition.Elements.Select(e => e.Id);
39+
bool isSuspend = false;
40+
bool continueExecution = true;
41+
var parentTerminateEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentTerminate, () =>
42+
{
43+
tokenSource.Cancel();
44+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
45+
foreach (var workflowElementInstance in workflowElementInstances)
46+
{
47+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentTerminate);
48+
}
49+
});
50+
var parentSuspendEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentSuspend, () =>
51+
{
52+
isSuspend = true;
53+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
54+
foreach (var workflowElementInstance in workflowElementInstances)
55+
{
56+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentSuspend);
57+
}
58+
});
59+
var parentResumeEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.ParentResume, () =>
60+
{
61+
isSuspend = false;
62+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
63+
foreach (var workflowElementInstance in workflowElementInstances)
64+
{
65+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentResume);
66+
}
67+
});
68+
var suspendEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.Suspend, () =>
69+
{
70+
isSuspend = true;
71+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
72+
foreach(var workflowElementInstance in workflowElementInstances)
73+
{
74+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentSuspend);
75+
}
76+
});
77+
var resumeEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.Resume, () =>
78+
{
79+
isSuspend = false;
80+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
81+
foreach (var workflowElementInstance in workflowElementInstances)
82+
{
83+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentResume);
84+
}
85+
});
86+
var terminateEvtListener = CMMNPlanItemTransitionListener.Listen(parameter, CMMNTransitions.Terminate, () =>
87+
{
88+
tokenSource.Cancel();
89+
var workflowElementInstances = parameter.WorkflowInstance.GetWorkflowElementInstancesByParentId(parameter.WorkflowElementInstance.Id);
90+
foreach (var workflowElementInstance in workflowElementInstances)
91+
{
92+
parameter.WorkflowInstance.MakeTransition(workflowElementInstance.Id, CMMNTransitions.ParentTerminate);
93+
}
94+
});
95+
while (continueExecution)
96+
{
97+
Thread.Sleep(100);
98+
if (isSuspend)
99+
{
100+
continue;
101+
}
102+
103+
try
104+
{
105+
tokenSource.Token.ThrowIfCancellationRequested();
106+
if (children.All(c => parameter.WorkflowInstance.IsWorkflowElementDefinitionFinished(c)))
107+
{
108+
continueExecution = false;
109+
parameter.WorkflowInstance.MakeTransition(parameter.WorkflowElementInstance.Id, CMMNTransitions.Complete);
110+
}
111+
}
112+
catch(OperationCanceledException)
113+
{
114+
continueExecution = false;
115+
}
116+
}
117+
118+
parentTerminateEvtListener.Unsubscribe();
119+
parentSuspendEvtListener.Unsubscribe();
120+
parentResumeEvtListener.Unsubscribe();
121+
suspendEvtListener.Unsubscribe();
122+
resumeEvtListener.Unsubscribe();
123+
terminateEvtListener.Unsubscribe();
124+
return parameter;
34125
}
35126
}
36127
}

src/CaseManagement.CMMN/CaseInstance/Processors/CMMNTaskProcessor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using System.Threading;
1+
using CaseManagement.CMMN.Domains;
2+
using System.Threading;
23
using System.Threading.Tasks;
3-
using CaseManagement.CMMN.Domains;
44

55
namespace CaseManagement.CMMN.CaseInstance.Processors
66
{
@@ -13,5 +13,7 @@ protected override Task Run(PlanItemProcessorParameter parameter, CancellationTo
1313
parameter.WorkflowInstance.MakeTransition(parameter.WorkflowElementInstance.Id, CMMNTransitions.Complete);
1414
return Task.CompletedTask;
1515
}
16+
17+
protected override void Unsubscribe() { }
1618
}
1719
}

src/CaseManagement.CMMN/CaseInstance/Processors/ICMMNPlanItemProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ namespace CaseManagement.CMMN.CaseInstance.Processors
77
public interface ICMMNPlanItemProcessor
88
{
99
CMMNWorkflowElementTypes Type { get; }
10-
Task Handle(PlanItemProcessorParameter parameter, CancellationToken token);
10+
Task<PlanItemProcessorParameter> Handle(PlanItemProcessorParameter parameter, CancellationToken token);
1111
}
1212
}

0 commit comments

Comments
 (0)