Skip to content

Commit 9ce4be1

Browse files
Ticket #9 : Try to support timerexpression
1 parent d3cf22d commit 9ce4be1

65 files changed

Lines changed: 1110 additions & 362 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CaseManagement.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.Website", "s
2525
EndProject
2626
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.CMMN.Host", "src\CaseManagement.CMMN.Host\CaseManagement.CMMN.Host.csproj", "{E4C5F767-299D-4D26-916B-59EC7C93CE90}"
2727
EndProject
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.Workflow.Tests", "tests\CaseManagement.Workflow.Tests\CaseManagement.Workflow.Tests.csproj", "{77FF9E1D-A705-4E04-84CA-FF42D3563F77}"
29+
EndProject
2830
Global
2931
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3032
Debug|Any CPU = Debug|Any CPU
@@ -55,6 +57,10 @@ Global
5557
{E4C5F767-299D-4D26-916B-59EC7C93CE90}.Debug|Any CPU.Build.0 = Debug|Any CPU
5658
{E4C5F767-299D-4D26-916B-59EC7C93CE90}.Release|Any CPU.ActiveCfg = Release|Any CPU
5759
{E4C5F767-299D-4D26-916B-59EC7C93CE90}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{77FF9E1D-A705-4E04-84CA-FF42D3563F77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{77FF9E1D-A705-4E04-84CA-FF42D3563F77}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{77FF9E1D-A705-4E04-84CA-FF42D3563F77}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{77FF9E1D-A705-4E04-84CA-FF42D3563F77}.Release|Any CPU.Build.0 = Release|Any CPU
5864
EndGlobalSection
5965
GlobalSection(SolutionProperties) = preSolution
6066
HideSolutionNode = FALSE
@@ -66,6 +72,7 @@ Global
6672
{2D288182-CD6B-46AF-B420-F2038875F6BC} = {A632EFC3-730B-46D7-B669-91962DFA8947}
6773
{1A146C2E-708E-4B50-AE46-37B415CEAFC1} = {D16A3E6D-32B6-44CF-9941-A9BDB9DFC6A7}
6874
{E4C5F767-299D-4D26-916B-59EC7C93CE90} = {CD2E7CFE-4E9C-4308-A0D3-41CD5AD90FD8}
75+
{77FF9E1D-A705-4E04-84CA-FF42D3563F77} = {A632EFC3-730B-46D7-B669-91962DFA8947}
6976
EndGlobalSection
7077
GlobalSection(ExtensibilityGlobals) = postSolution
7178
SolutionGuid = {D2CFBF2E-D493-42F7-B339-01A3070C2B5E}

Doc.docx

-5.47 KB
Binary file not shown.

src/CaseManagement.BPMN/ProcessInstance/Processors/BPMNReceiveTaskProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class BPMNReceiveTaskProcessor : IProcessFlowElementProcessor
1313
public Task Handle(ProcessFlowInstance pf, ProcessFlowInstanceElement pfe)
1414
{
1515
var receiveTask = pfe as BPMNReceiveTask;
16-
pf.LaunchElement(pfe);
16+
pf.StartElement(pfe);
1717
pf.CompleteElement(pfe);
1818
return Task.FromResult(0);
1919
}

src/CaseManagement.BPMN/ProcessInstance/Processors/BPMNServiceTaskProcessor.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using CaseManagement.BPMN.Domains;
22
using CaseManagement.Workflow.Domains;
33
using CaseManagement.Workflow.Engine;
4-
using CaseManagement.Workflow.Infrastructure;
54
using System;
65
using System.Threading.Tasks;
76

@@ -13,7 +12,7 @@ public class BPMNServiceTaskProcessor : IProcessFlowElementProcessor
1312

1413
public async Task Handle(ProcessFlowInstance pf, ProcessFlowInstanceElement pfe)
1514
{
16-
pf.LaunchElement(pfe);
15+
pf.StartElement(pfe);
1716
var serviceTask = (BPMNServiceTask)pfe;
1817
var type = Type.GetType(serviceTask.FullQualifiedName);
1918
// var instance = Activator.CreateInstance(type) as WorkflowTaskDelegate;

src/CaseManagement.CMMN.Host/CaseManagement.CMMN.Host.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<ProjectReference Include="..\CaseManagement.CMMN\CaseManagement.CMMN.csproj" />
1111
</ItemGroup>
1212
<ItemGroup>
13-
<Folder Include="Cmmns\" />
14-
</ItemGroup>
15-
<ItemGroup>
13+
<None Update="Cmmns\caseWithTimerEventListener.cmmn">
14+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
15+
</None>
1616
<None Update="Cmmns\firstDiagram.cmmn">
1717
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
1818
</None>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<cmmn:definitions xmlns:dc="http://www.omg.org/spec/CMMN/20151109/DC" xmlns:cmmndi="http://www.omg.org/spec/CMMN/20151109/CMMNDI" xmlns:cmmn="http://www.omg.org/spec/CMMN/20151109/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/CMMN/20151109/DI" id="caseWithTimerEventListener" targetNamespace="http://bpmn.io/schema/cmmn" exporter="cmmn-js (https://demo.bpmn.io/cmmn)" exporterVersion="0.19.2">
3+
<cmmn:case id="Case_0d1ujq8">
4+
<cmmn:casePlanModel id="CasePlanModel_0qazg9e" name="A case with TimerEvent">
5+
<cmmn:planItem id="PlanItem_04t8i1g" name="Send EMAIL" definitionRef="Task_1xaq99o">
6+
<cmmn:entryCriterion id="EntryCriterion_1emixlz" sentryRef="Sentry_1wpskn6" />
7+
</cmmn:planItem>
8+
<cmmn:planItem id="PlanItem_1wwlyh1" name="Timer" definitionRef="TimerEventListener_0shtnuf" />
9+
<cmmn:sentry id="Sentry_1wpskn6">
10+
<cmmn:planItemOnPart id="PlanItemOnPart_1xvq8dc" sourceRef="PlanItem_1wwlyh1">
11+
<cmmn:standardEvent>occur</cmmn:standardEvent>
12+
</cmmn:planItemOnPart>
13+
</cmmn:sentry>
14+
<cmmn:task id="Task_1xaq99o" name="Send EMAIL" />
15+
<cmmn:timerEventListener id="TimerEventListener_0shtnuf">
16+
<cmmn:timerExpression>R2/P0Y0M0DT0H0M10S</cmmn:timerExpression>
17+
</cmmn:timerEventListener>
18+
</cmmn:casePlanModel>
19+
</cmmn:case>
20+
<cmmndi:CMMNDI>
21+
<cmmndi:CMMNDiagram id="CMMNDiagram_1">
22+
<cmmndi:Size width="500" height="500" />
23+
<cmmndi:CMMNShape id="DI_CasePlanModel_0qazg9e" cmmnElementRef="CasePlanModel_0qazg9e">
24+
<dc:Bounds x="156" y="99" width="516" height="161" />
25+
<cmmndi:CMMNLabel />
26+
</cmmndi:CMMNShape>
27+
<cmmndi:CMMNShape id="PlanItem_04t8i1g_di" cmmnElementRef="PlanItem_04t8i1g">
28+
<dc:Bounds x="473" y="132" width="100" height="80" />
29+
<cmmndi:CMMNLabel />
30+
</cmmndi:CMMNShape>
31+
<cmmndi:CMMNShape id="EntryCriterion_1emixlz_di" cmmnElementRef="EntryCriterion_1emixlz">
32+
<dc:Bounds x="463" y="158" width="20" height="28" />
33+
<cmmndi:CMMNLabel />
34+
</cmmndi:CMMNShape>
35+
<cmmndi:CMMNEdge id="PlanItemOnPart_1xvq8dc_di" cmmnElementRef="PlanItemOnPart_1xvq8dc" targetCMMNElementRef="EntryCriterion_1emixlz" isStandardEventVisible="true">
36+
<di:waypoint x="315" y="172" />
37+
<di:waypoint x="463" y="172" />
38+
<cmmndi:CMMNLabel>
39+
<dc:Bounds x="372" y="162" width="34" height="13" />
40+
</cmmndi:CMMNLabel>
41+
</cmmndi:CMMNEdge>
42+
<cmmndi:CMMNShape id="PlanItem_05m34bi_di" cmmnElementRef="PlanItem_1wwlyh1">
43+
<dc:Bounds x="279" y="154" width="36" height="36" />
44+
<cmmndi:CMMNLabel>
45+
<dc:Bounds x="297" y="190" width="0" height="0" />
46+
</cmmndi:CMMNLabel>
47+
</cmmndi:CMMNShape>
48+
</cmmndi:CMMNDiagram>
49+
</cmmndi:CMMNDI>
50+
</cmmn:definitions>

src/CaseManagement.CMMN/Apis/CaseInstancesController.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ private static JObject ToDto(FindResponse<ProcessFlowInstanceExecutionStep> resp
174174
{
175175
{ "start_datetime", r.StartDateTime },
176176
{ "end_datetime", r.EndDateTime },
177-
{ "name", r.Element.Name },
178-
{ "id", r.Element.Id }
177+
{ "name", r.ElementName },
178+
{ "id", r.ElementId }
179179
})) }
180180
};
181181
}
@@ -187,13 +187,20 @@ private static JObject ToDto(FindResponse<ProcessFlowInstance> resp)
187187
{ "start_index", resp.StartIndex },
188188
{ "total_length", resp.TotalLength },
189189
{ "count", resp.Count },
190-
{ "content", new JArray(resp.Content.Select(r => new JObject
191-
{
192-
{ "id", r.Id },
193-
{ "name", r.ProcessFlowName },
194-
{ "status", Enum.GetName(typeof(ProcessFlowInstanceStatus), r.Status).ToLowerInvariant() },
195-
{ "template_id", r.ProcessFlowTemplateId },
196-
{ "create_datetime", r.CreateDateTime }
190+
{ "content", new JArray(resp.Content.Select(r => {
191+
var result = new JObject
192+
{
193+
{ "id", r.Id },
194+
{ "name", r.ProcessFlowName },
195+
{ "template_id", r.ProcessFlowTemplateId },
196+
{ "create_datetime", r.CreateDateTime }
197+
};
198+
if (r.Status != null)
199+
{
200+
result.Add("status", Enum.GetName(typeof(ProcessFlowInstanceStatus), r.Status).ToLowerInvariant());
201+
}
202+
203+
return result;
197204
})) }
198205
};
199206
}
@@ -206,9 +213,13 @@ private static JObject ToDto(ProcessFlowInstance flowInstance)
206213
{ "create_datetime", flowInstance.CreateDateTime },
207214
{ "template_id", flowInstance.ProcessFlowTemplateId },
208215
{ "name", flowInstance.ProcessFlowName },
209-
{ "context", ToDto(flowInstance.ExecutionContext) },
210-
{ "status", Enum.GetName(typeof(ProcessFlowInstanceStatus), flowInstance.Status).ToLowerInvariant() }
216+
{ "context", ToDto(flowInstance.ExecutionContext) }
211217
};
218+
if (flowInstance.Status != null)
219+
{
220+
result.Add("status", Enum.GetName(typeof(ProcessFlowInstanceStatus), flowInstance.Status).ToLowerInvariant());
221+
}
222+
212223
var planItems = new JArray();
213224
foreach(var planItem in flowInstance.Elements.Where(e => e is CMMNPlanItem).Cast<CMMNPlanItem>())
214225
{
@@ -232,12 +243,17 @@ private static JObject ToDto(ProcessFlowInstanceExecutionContext context)
232243

233244
private static JObject ToDto(CMMNPlanItem planItem)
234245
{
235-
return new JObject
246+
var result = new JObject
236247
{
237248
{ "id", planItem.Id },
238-
{ "name", planItem.Name },
239-
{ "status", Enum.GetName(typeof(ProcessFlowInstanceElementStatus), planItem.Status).ToLowerInvariant() }
249+
{ "name", planItem.Name }
240250
};
251+
if (planItem.Status != null)
252+
{
253+
result.Add("status", Enum.GetName(typeof(ProcessFlowInstanceElementStatus), planItem.Status).ToLowerInvariant());
254+
}
255+
256+
return result;
241257
}
242258

243259
private static ActionResult ToError(ICollection<KeyValuePair<string, string>> errors, HttpStatusCode statusCode, HttpRequest request)

src/CaseManagement.CMMN/ApplicationBuilderExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
using CaseManagement.CMMN.CaseInstance.EventHandlers;
22
using CaseManagement.Workflow.Domains.Events;
33
using CaseManagement.Workflow.Infrastructure.EvtBus;
4+
using Hangfire;
45

56
namespace Microsoft.AspNetCore.Builder
67
{
78
public static class ApplicationBuilderExtensions
89
{
910
public static IApplicationBuilder UseCMMN(this IApplicationBuilder appBuilder)
1011
{
12+
appBuilder.UseHangfireServer();
1113
appBuilder.ConfigureEventBus();
1214
appBuilder.UseMvc();
1315
return appBuilder;
@@ -19,6 +21,7 @@ private static void ConfigureEventBus(this IApplicationBuilder app)
1921
evtBus.Subscribe<ProcessFlowInstanceCreatedEvent, ProcessFlowInstanceCreatedEventHandler>();
2022
evtBus.Subscribe<ProcessFlowInstanceLaunchedEvent, ProcessFlowInstanceLaunchedEventHandler>();
2123
evtBus.Subscribe<ProcessFlowInstanceFormConfirmedEvent, ProcessFlowInstanceFormConfirmedEventHandler>();
24+
evtBus.Subscribe<ProcessFlowElementLaunchedEvent, ProcessFlowElementLaunchedEventHandler>();
2225
}
2326
}
2427
}

src/CaseManagement.CMMN/CaseInstance/CommandHandlers/CreateCaseInstanceCommandHandler.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ private static CMMNPlanItemDefinition BuildPlanItemDefinition(tPlanItemDefinitio
102102
return BuildTask((tTask)planItemDef);
103103
}
104104

105+
if (planItemDef is tTimerEventListener)
106+
{
107+
return BuildTimerEventListener((tTimerEventListener)planItemDef);
108+
}
109+
105110
return null;
106111
}
107112

@@ -150,6 +155,20 @@ private static CMMNPlanItemDefinition BuildHumanTask(tHumanTask humanTask)
150155
return new CMMNHumanTask(humanTask.name) { FormId = humanTask.caseFormRef, IsBlocking = humanTask.isBlocking };
151156
}
152157

158+
private static CMMNPlanItemDefinition BuildTimerEventListener(tTimerEventListener timerEventListener)
159+
{
160+
var result = new CMMNTimerEventListener(timerEventListener.name);
161+
if (timerEventListener.timerExpression != null)
162+
{
163+
result.TimerExpression = new CMMNExpression(timerEventListener.timerExpression.language)
164+
{
165+
Body = timerEventListener.timerExpression.Text.First()
166+
};
167+
}
168+
169+
return result;
170+
}
171+
153172
private static CMMNSEntry BuildSEntry(tSentry sEntry)
154173
{
155174
var result = new CMMNSEntry(sEntry.name);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using CaseManagement.Workflow.Domains;
2+
using CaseManagement.Workflow.Domains.Events;
3+
using CaseManagement.Workflow.Engine;
4+
using CaseManagement.Workflow.Infrastructure.EvtBus;
5+
using CaseManagement.Workflow.Persistence;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
9+
namespace CaseManagement.CMMN.CaseInstance.EventHandlers
10+
{
11+
public class ProcessFlowElementLaunchedEventHandler : IDomainEventHandler<ProcessFlowElementLaunchedEvent>
12+
{
13+
private readonly IProcessFlowElementProcessorFactory _processFlowElementProcessorFactory;
14+
private readonly IProcessFlowInstanceQueryRepository _processFlowInstanceQueryRepository;
15+
private readonly IProcessFlowInstanceCommandRepository _processFlowInstanceCommandRepository;
16+
17+
public ProcessFlowElementLaunchedEventHandler(IProcessFlowElementProcessorFactory processFlowElementProcessorFactory, IProcessFlowInstanceQueryRepository processFlowInstanceQueryRepository, IProcessFlowInstanceCommandRepository processFlowInstanceCommandRepository)
18+
{
19+
_processFlowElementProcessorFactory = processFlowElementProcessorFactory;
20+
_processFlowInstanceQueryRepository = processFlowInstanceQueryRepository;
21+
_processFlowInstanceCommandRepository = processFlowInstanceCommandRepository;
22+
}
23+
24+
public async Task Handle(ProcessFlowElementLaunchedEvent @event)
25+
{
26+
var flowInstance = await _processFlowInstanceQueryRepository.FindFlowInstanceById(@event.ProcessFlowInstanceId);
27+
await Start(flowInstance, flowInstance.Elements.First(e => e.Id == @event.ProcessFlowInstanceElementId));
28+
_processFlowInstanceCommandRepository.Update(flowInstance);
29+
await _processFlowInstanceCommandRepository.SaveChanges();
30+
}
31+
32+
private async Task Start(ProcessFlowInstance processFlowInstance, ProcessFlowInstanceElement elt)
33+
{
34+
var processor = _processFlowElementProcessorFactory.Build(elt);
35+
await processor.Handle(processFlowInstance, elt);
36+
if (elt.Status != ProcessFlowInstanceElementStatus.Finished)
37+
{
38+
return;
39+
}
40+
41+
var nextElts = processFlowInstance.NextElements(elt.Id);
42+
if (!nextElts.Any())
43+
{
44+
return;
45+
}
46+
47+
foreach (var nextElt in nextElts)
48+
{
49+
await Start(processFlowInstance, nextElt);
50+
}
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)