public async Task When_Execute_ServiceTask_With_CSHARPCallback() { const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "message", string.Empty) .AddStartEvent("1", "evt", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddServiceTask("2", "name", _ => { _.SetCallback(typeof(GetWeatherInformationDelegate).FullName); }) .AddSequenceFlow("seq1", "sequence", "1", "2") .Build(); var jobServer = FakeCaseJobServer.New(); try { await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); jobServer.Start(); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.MonitorProcessInstance(processInstance.AggregateId, (c) => { if (c == null) { return(false); } return(c.ElementInstances.Any()); }, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, null, CancellationToken.None); casePlanInstance = await jobServer.MonitorProcessInstance(processInstance.AggregateId, (c) => { if (c == null) { return(false); } return(c.ElementInstances.Count() == 2); }, CancellationToken.None); var startEventInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1"); var serviceTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); Assert.Equal(FlowNodeStates.Active, startEventInstance.State); Assert.Equal(ActivityStates.COMPLETED, serviceTaskInstance.ActivityState); Assert.Equal(FlowNodeStates.Complete, serviceTaskInstance.State); } finally { jobServer.Stop(); } }
public async Task When_Execute_ConditionalSequenceFlow() { const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "message", "item") .AddItemDef("item", ItemKinds.Information, false, typeof(PersonParameter).FullName) .AddStartEvent("1", "evt", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddEmptyTask("2", "name") .AddEmptyTask("3", "name") .AddSequenceFlow("seq1", "sequence", "1", "2", "context.GetIncomingMessage(\"Firstname\") == \"user\"") .AddSequenceFlow("seq2", "sequence", "1", "3", "context.GetIncomingMessage(\"Firstname\") == \"baduser\"") .Build(); var jobServer = FakeCaseJobServer.New(); try { await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); jobServer.Start(); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.MonitorProcessInstance(processInstance.AggregateId, (c) => { if (c == null) { return(false); } return(c.ElementInstances.Any()); }, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, new PersonParameter { Firstname = "user" }, CancellationToken.None); casePlanInstance = await jobServer.MonitorProcessInstance(processInstance.AggregateId, (c) => { if (c == null) { return(false); } return(c.ElementInstances.Count() == 2); }, CancellationToken.None); var startEventInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1"); var firstEmptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); Assert.Equal(FlowNodeStates.Active, startEventInstance.State); Assert.Equal(ActivityStates.COMPLETED, firstEmptyTaskInstance.ActivityState); Assert.Equal(FlowNodeStates.Complete, firstEmptyTaskInstance.State); } finally { jobServer.Stop(); } }
public async Task When_Execute_BoundaryEvent() { var humanTaskInstanceId = Guid.NewGuid().ToString(); const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "message", "item") .AddMessage("humanTaskCreated", "humanTaskCreated", "item") .AddItemDef("item", ItemKinds.Information, false, typeof(PersonParameter).FullName) .AddStartEvent("1", "evt") .AddUserTask("2", "userTask", (cb) => { cb.SetWsHumanTask("dressAppropriate"); cb.AddBoundaryEventRef("3"); }) .AddBoundaryEvent("3", "messageReceived", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddEmptyTask("4", "emptyTask") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "2", "3") .AddSequenceFlow("seq3", "sequence", "3", "4") .Build(); var jobServer = FakeCaseJobServer.New(); jobServer.HttpMessageHandler.Protected() .As <IHttpMessageHandler>() .Setup(x => x.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new HttpResponseMessage { Content = new StringContent("{ 'id' : '" + humanTaskInstanceId + "', 'defId': 'defId' }") }); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, new PersonParameter { }, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var ei = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); await jobServer.EnqueueStateTransition(casePlanInstance.AggregateId, ei.EltId, "COMPLETED", new JObject(), CancellationToken.None); casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var executionPath = casePlanInstance.ExecutionPathLst.First(); Assert.True(casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1").State == FlowNodeStates.Complete); Assert.True(casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2").State == FlowNodeStates.Complete); Assert.True(casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "4").State == FlowNodeStates.Complete); Assert.Equal(1, executionPath.Pointers.First(p => p.FlowNodeId == "1").Outgoing.Count()); Assert.Equal(1, executionPath.Pointers.First(p => p.FlowNodeId == "2").Incoming.Count()); Assert.Equal(1, executionPath.Pointers.First(p => p.FlowNodeId == "2").Outgoing.Count()); Assert.Equal(2, executionPath.Pointers.First(p => p.FlowNodeId == "3").Incoming.Count()); Assert.Equal(2, executionPath.Pointers.First(p => p.FlowNodeId == "4").Incoming.Count()); }
public async Task When_Execute_HumanTaskWithBoundaryEvent() { var humanTaskInstanceId = Guid.NewGuid().ToString(); const string messageName = "humanTaskCreated"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "humanTaskCreated", "item") .AddItemDef("item", ItemKinds.Information, false, typeof(HumanTaskParameter).FullName) .AddStartEvent("1", "evt") .AddUserTask("2", "userTask", (cb) => { cb.SetWsHumanTask("dressAppropriate"); cb.AddBoundaryEventRef("3"); }) .AddBoundaryEvent("3", "humanTaskCreated", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddEmptyTask("4", "firstEmptyTask") .AddEmptyTask("5", "secondEmptyTask") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "2", "3") .AddSequenceFlow("seq3", "sequence", "3", "4") .AddSequenceFlow("seq4", "sequence", "2", "5") .Build(); var jobServer = FakeCaseJobServer.New(); jobServer.Start(); jobServer.HttpMessageHandler.Protected() .As <IHttpMessageHandler>() .Setup(x => x.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new HttpResponseMessage { Content = new StringContent("{ 'id' : '" + humanTaskInstanceId + "', 'defId': 'defId' }") }); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var result = await jobServer.MonitoringProcessInstance(processInstance.AggregateId, (p) => { var elt = p.ElementInstances.FirstOrDefault(_ => _.FlowNodeId == "4"); return(elt != null && elt.State == FlowNodeStates.Complete); }, CancellationToken.None); var ei = result.ElementInstances.First(_ => _.FlowNodeId == "2"); await jobServer.EnqueueStateTransition(result.AggregateId, ei.EltId, "COMPLETED", new JObject(), CancellationToken.None); result = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); Assert.True(result.ElementInstances.First(_ => _.FlowNodeId == "1").State == FlowNodeStates.Complete); Assert.True(result.ElementInstances.First(_ => _.FlowNodeId == "2").State == FlowNodeStates.Complete); Assert.True(result.ElementInstances.First(_ => _.FlowNodeId == "4").State == FlowNodeStates.Complete); jobServer.Stop(); }
public async Task When_Execute_ParallelGateway() { const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "message", "item") .AddItemDef("item", ItemKinds.Information, false, typeof(PersonParameter).FullName) .AddStartEvent("1", "evt", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddParallelGateway("2", "gateway", GatewayDirections.DIVERGING) .AddEmptyTask("3", "name") .AddEmptyTask("4", "name") .AddParallelGateway("5", "gateway", GatewayDirections.CONVERGING) .AddEmptyTask("6", "name") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "2", "3") .AddSequenceFlow("seq3", "sequence", "2", "4") .AddSequenceFlow("seq4", "sequence", "3", "5") .AddSequenceFlow("seq5", "sequence", "4", "5") .AddSequenceFlow("seq6", "sequence", "5", "6") .Build(); var jobServer = FakeCaseJobServer.New(); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, new PersonParameter { Firstname = "user" }, CancellationToken.None); casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var startEventInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1"); var firstParallelGateway = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); var firstEmptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "3"); var secondEmptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "4"); var secondParallelGateway = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "5"); var thirdEmptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "6"); var secondParallelGatewayExecPointer = casePlanInstance.ExecutionPathLst.First().Pointers.First(_ => _.FlowNodeId == "5"); var thirdEmptyTaskExecPointer = casePlanInstance.ExecutionPathLst.First().Pointers.First(_ => _.FlowNodeId == "6"); Assert.Equal(FlowNodeStates.Active, startEventInstance.State); Assert.Equal(FlowNodeStates.Complete, firstParallelGateway.State); Assert.Equal(FlowNodeStates.Complete, firstEmptyTaskInstance.State); Assert.Equal(FlowNodeStates.Complete, secondEmptyTaskInstance.State); Assert.Equal(FlowNodeStates.Complete, secondParallelGateway.State); Assert.Equal(FlowNodeStates.Complete, thirdEmptyTaskInstance.State); Assert.Equal(2, secondParallelGatewayExecPointer.Incoming.Count()); Assert.Equal(2, thirdEmptyTaskExecPointer.Incoming.Count()); }
public async Task When_Execute_UserTask() { var humanTaskInstanceId = Guid.NewGuid().ToString(); var processInstance = ProcessInstanceBuilder.New("processFile") .AddStartEvent("1", "evt") .AddServiceTask("2", "serviceTask", (cb) => { cb.SetDelegate("GetWeatherInformationDelegate"); }) .AddUserTask("3", "userTask", (cb) => { cb.SetWsHumanTask("dressAppropriate", new Dictionary <string, string> { { "degree", "context.GetIncomingMessage(\"weatherInformation\", \"degree\")" }, { "city", "context.GetIncomingMessage(\"weatherInformation\", \"city\")" } }); }) .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "2", "3") .Build(); var jobServer = FakeCaseJobServer.New(); jobServer.HttpMessageHandler.Protected() .As <IHttpMessageHandler>() .Setup(x => x.SendAsync(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>())) .ReturnsAsync(new HttpResponseMessage { Content = new StringContent("{ 'id' : '" + humanTaskInstanceId + "', 'defId': 'defId' }") }); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var ei = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "3"); await jobServer.EnqueueStateTransition(casePlanInstance.AggregateId, ei.EltId, "COMPLETED", new JObject(), CancellationToken.None); casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); Assert.True(casePlanInstance.ElementInstances.All(_ => _.State == FlowNodeStates.Complete)); }
public async Task When_Execute_StartEvent_With_MessageEventDefinition() { const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("processFile") .AddMessage(messageName, "message", string.Empty) .AddStartEvent("1", "evt", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef("message"); }); }) .AddEmptyTask("2", "name", _ => { _.SetStartQuantity(2); }) .AddSequenceFlow("seq1", "sequence", "1", "2") .Build(); var jobServer = FakeCaseJobServer.New(); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, null, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, null, CancellationToken.None); casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var startEventInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1"); var emptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); Assert.Equal(FlowNodeStates.Active, startEventInstance.State); Assert.Equal(ActivityStates.COMPLETED, emptyTaskInstance.ActivityState); Assert.Equal(FlowNodeStates.Complete, emptyTaskInstance.State); Assert.Equal(1, casePlanInstance.ExecutionPathLst.Count()); Assert.Equal(1, casePlanInstance.ExecutionPathLst.First().ActivePointers.Count()); Assert.Equal(4, casePlanInstance.ExecutionPathLst.First().Pointers.Count()); }
public async Task When_Execute_InclusiveGateway() { const string messageName = "message"; var processInstance = ProcessInstanceBuilder.New("1") .AddMessage(messageName, "message", "item") .AddItemDef("item", ItemKinds.Information, false, typeof(PersonParameter).FullName) .AddStartEvent("1", "evt", _ => { _.AddMessageEvtDef("id", cb => { cb.SetMessageRef(messageName); }); }) .AddInclusiveGateway("2", "gateway", GatewayDirections.DIVERGING, "5") .AddEmptyTask("3", "name") .AddEmptyTask("4", "name") .AddEmptyTask("5", "name") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "2", "3", "context.GetIncomingMessage(\"Firstname\") == \"user1\"") .AddSequenceFlow("seq3", "sequence", "2", "4", "context.GetIncomingMessage(\"Firstname\") == \"user2\"") .AddSequenceFlow("seq4", "sequence", "2", "5") .Build(); var jobServer = FakeCaseJobServer.New(); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); await jobServer.EnqueueMessage(processInstance.AggregateId, messageName, new PersonParameter { }, CancellationToken.None); casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); var startEventInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "1"); var inclusiveGatewayInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "2"); var firstEmptyTaskInstance = casePlanInstance.ElementInstances.First(_ => _.FlowNodeId == "5"); Assert.Equal(FlowNodeStates.Active, startEventInstance.State); Assert.Equal(FlowNodeStates.Complete, inclusiveGatewayInstance.State); Assert.Equal(FlowNodeStates.Complete, firstEmptyTaskInstance.State); }
public async Task When_Execute_Sequence_Of_Empty_Tasks() { var processInstance = ProcessInstanceBuilder.New("processFile") .AddStartEvent("1", "evt") .AddEmptyTask("2", "name") .AddEmptyTask("3", "name") .AddEmptyTask("4", "name") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "1", "3") .AddSequenceFlow("seq3", "sequence", "2", "4") .AddSequenceFlow("seq3", "sequence", "3", "4") .Build(); var jobServer = FakeCaseJobServer.New(); try { await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); jobServer.Start(); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.MonitorProcessInstance(processInstance.AggregateId, (c) => { if (c == null) { return(false); } return(c.ElementInstances.Count() == 10); }, CancellationToken.None); Assert.Equal(10, casePlanInstance.ElementInstances.Count()); } finally { jobServer.Stop(); } }
public async Task When_Execute_Sequence_Of_Empty_Tasks() { var processInstance = ProcessInstanceBuilder.New("processFile") .AddStartEvent("1", "evt") .AddEmptyTask("2", "name") .AddEmptyTask("3", "name") .AddEmptyTask("4", "name") .AddSequenceFlow("seq1", "sequence", "1", "2") .AddSequenceFlow("seq2", "sequence", "1", "3") .AddSequenceFlow("seq3", "sequence", "2", "4") .AddSequenceFlow("seq3", "sequence", "3", "4") .Build(); var jobServer = FakeCaseJobServer.New(); await jobServer.RegisterProcessInstance(processInstance, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); await jobServer.EnqueueProcessInstance(processInstance.AggregateId, true, CancellationToken.None); var casePlanInstance = await jobServer.Get(processInstance.AggregateId, CancellationToken.None); Assert.Equal(10, casePlanInstance.ElementInstances.Count()); }
public static ICollection <ProcessInstanceAggregate> BuildInstances(tDefinitions definitions, string processFileId) { var result = new List <ProcessInstanceAggregate>(); var processes = definitions.Items.Where(_ => _ is tProcess).Cast <tProcess>(); var messages = definitions.Items.Where(_ => _ is tMessage).Cast <tMessage>(); var itemDefs = definitions.Items.Where(_ => _ is tItemDefinition).Cast <tItemDefinition>(); foreach (var process in processes) { var builder = ProcessInstanceBuilder.New(processFileId); foreach (var message in messages) { builder.AddMessage(message.id, message.name, message.itemRef?.Name); } foreach (var itemDef in itemDefs) { builder.AddItemDef(itemDef.id, ItemKinds.Information, false, null); } foreach (var item in process.Items) { tStartEvent startEvt; tEndEvent endEvt; tTask task; tSequenceFlow sequenceFlow; tExclusiveGateway exclusiveGateway; tUserTask userTask; tServiceTask serviceTask; tBoundaryEvent boundaryEvent; if ((startEvt = item as tStartEvent) != null) { builder.AddStartEvent(startEvt.id, startEvt.name, cb => { Update(cb, startEvt); }); } else if ((endEvt = item as tEndEvent) != null) { builder.AddEndEvent(endEvt.id, endEvt.name); } else if ((userTask = item as tUserTask) != null) { builder.AddUserTask(userTask.id, userTask.name, (cb) => { Update(cb, item.id, process.Items); if (userTask.implementation == BPMNConstants.UserTaskImplementations.WSHUMANTASK) { var parameters = userTask.extensionElements?.Any.FirstOrDefault(_ => _.Name == "cmg:parameters"); List <tParameter> pars = new List <tParameter>(); if (parameters != null) { var xmlSerializer = new XmlSerializer(typeof(tParameter), "http://www.omg.org/spec/BPMN/20100524/MODEL"); foreach (XmlNode child in parameters.ChildNodes) { using (var txtReader = new StringReader(child.OuterXml)) { pars.Add((tParameter)xmlSerializer.Deserialize(txtReader)); } } } cb.SetWsHumanTask(userTask.wsHumanTaskDefName, pars.ToDictionary(_ => _.key, _ => _.value)); } }); } else if ((serviceTask = item as tServiceTask) != null) { builder.AddServiceTask(serviceTask.id, serviceTask.name, (cb) => { Update(cb, item.id, process.Items); if (serviceTask.implementation == BPMNConstants.ServiceTaskImplementations.CALLBACK) { cb.SetDelegate(serviceTask.delegateId); } }); } else if ((task = item as tTask) != null) { builder.AddEmptyTask(task.id, task.name, (cb) => { Update(cb, item.id, process.Items); }); } else if ((sequenceFlow = item as tSequenceFlow) != null) { builder.AddSequenceFlow(sequenceFlow.id, sequenceFlow.name, sequenceFlow.sourceRef, sequenceFlow.targetRef, sequenceFlow.conditionExpression?.Text.First()); } else if ((exclusiveGateway = item as tExclusiveGateway) != null) { builder.AddExclusiveGateway(exclusiveGateway.id, exclusiveGateway.name, MAPPING_GATEWAY_DIRECTIONS[exclusiveGateway.gatewayDirection], exclusiveGateway.@default); } else if ((boundaryEvent = item as tBoundaryEvent) != null) { builder.AddBoundaryEvent(boundaryEvent.id, boundaryEvent.name, cb => { Update(cb, boundaryEvent); }); } } result.Add(builder.Build()); } return(result); }