Skip to content

Commit

Permalink
Ticket #4 : Can launch case instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Thierry Habart authored and thabart committed Nov 27, 2019
1 parent 4c77e49 commit 630243a
Show file tree
Hide file tree
Showing 94 changed files with 1,668 additions and 839 deletions.
14 changes: 0 additions & 14 deletions CaseManagement.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02. CMMN", "02. CMMN", "{CD
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.CMMN", "src\CaseManagement.CMMN\CaseManagement.CMMN.csproj", "{CE4424E0-4EC0-45D0-9791-91864EDEA89B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.BPMN.Tests", "tests\CaseManagement.BPMN.Tests\CaseManagement.BPMN.Tests.csproj", "{2FC26859-C75B-4C4C-82AE-E46D8B4996DD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.CMMN.Tests", "tests\CaseManagement.CMMN.Tests\CaseManagement.CMMN.Tests.csproj", "{5BBD9089-565C-47F9-A284-65A41BEB3EFC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00. Other", "00. Other", "{9360C4A1-A2AA-4493-BBDC-4044D78D8F4B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaseManagement.Workflow", "src\CaseManagement.Workflow\CaseManagement.Workflow.csproj", "{E3E72DF1-F427-4FEA-8F84-FB194EA20D07}"
Expand All @@ -37,14 +33,6 @@ Global
{CE4424E0-4EC0-45D0-9791-91864EDEA89B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE4424E0-4EC0-45D0-9791-91864EDEA89B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE4424E0-4EC0-45D0-9791-91864EDEA89B}.Release|Any CPU.Build.0 = Release|Any CPU
{2FC26859-C75B-4C4C-82AE-E46D8B4996DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FC26859-C75B-4C4C-82AE-E46D8B4996DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FC26859-C75B-4C4C-82AE-E46D8B4996DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FC26859-C75B-4C4C-82AE-E46D8B4996DD}.Release|Any CPU.Build.0 = Release|Any CPU
{5BBD9089-565C-47F9-A284-65A41BEB3EFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BBD9089-565C-47F9-A284-65A41BEB3EFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BBD9089-565C-47F9-A284-65A41BEB3EFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BBD9089-565C-47F9-A284-65A41BEB3EFC}.Release|Any CPU.Build.0 = Release|Any CPU
{E3E72DF1-F427-4FEA-8F84-FB194EA20D07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3E72DF1-F427-4FEA-8F84-FB194EA20D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3E72DF1-F427-4FEA-8F84-FB194EA20D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -60,8 +48,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{D7A0C87C-CF5B-48CF-9A0F-FE7F6248BB30} = {4E0AA29C-B5C1-4888-BB6E-7141E7DBFB51}
{CE4424E0-4EC0-45D0-9791-91864EDEA89B} = {CD2E7CFE-4E9C-4308-A0D3-41CD5AD90FD8}
{2FC26859-C75B-4C4C-82AE-E46D8B4996DD} = {A632EFC3-730B-46D7-B669-91962DFA8947}
{5BBD9089-565C-47F9-A284-65A41BEB3EFC} = {A632EFC3-730B-46D7-B669-91962DFA8947}
{E3E72DF1-F427-4FEA-8F84-FB194EA20D07} = {9360C4A1-A2AA-4493-BBDC-4044D78D8F4B}
{2D288182-CD6B-46AF-B420-F2038875F6BC} = {A632EFC3-730B-46D7-B669-91962DFA8947}
EndGlobalSection
Expand Down
Binary file modified Doc.docx
Binary file not shown.
63 changes: 57 additions & 6 deletions src/CaseManagement.CMMN/Apis/CaseInstancesController.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using CaseManagement.CMMN.CaseInstance.Handlers;
using CaseManagement.CMMN.CaseInstance.CommandHandlers;
using CaseManagement.CMMN.CaseInstance.Commands;
using CaseManagement.CMMN.Domains;
using CaseManagement.Workflow.Domains;
using CaseManagement.Workflow.Persistence;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

Expand All @@ -12,10 +17,15 @@ public class CaseInstancesController : Controller
{
private readonly ICreateCaseInstanceCommandHandler _createCaseInstanceCommandHandler;
private readonly ILaunchCaseInstanceCommandHandler _launchCaseInstanceCommandHandler;
private readonly IConfirmFormCommandHandler _confirmFormCommandHandler;
private readonly IProcessFlowInstanceQueryRepository _processFlowInstanceQueryRepository;

public CaseInstancesController(ICreateCaseInstanceCommandHandler createCaseInstanceCommandHandler, ILaunchCaseInstanceCommandHandler launchCaseInstanceCommandHandler)
public CaseInstancesController(ICreateCaseInstanceCommandHandler createCaseInstanceCommandHandler, ILaunchCaseInstanceCommandHandler launchCaseInstanceCommandHandler, IConfirmFormCommandHandler confirmFormCommandHandler, IProcessFlowInstanceQueryRepository processFlowInstanceQueryRepository)
{
_createCaseInstanceCommandHandler = createCaseInstanceCommandHandler;
_launchCaseInstanceCommandHandler = launchCaseInstanceCommandHandler;
_confirmFormCommandHandler = confirmFormCommandHandler;
_processFlowInstanceQueryRepository = processFlowInstanceQueryRepository;
}

[HttpPost]
Expand All @@ -36,13 +46,54 @@ public async Task<IActionResult> Create([FromBody] CreateCaseInstanceCommand cre
public async Task<IActionResult> Launch(string id)
{
await _launchCaseInstanceCommandHandler.Handle(new LaunchCaseInstanceCommand { CaseInstanceId = id });
return null;
return new OkResult();
}

[HttpPost("{id}/confirm/{elt}")]
public async Task<IActionResult> ConfirmForm(string id, string elt, [FromBody] ConfirmFormCommand confirmForm)
{
await _confirmFormCommandHandler.Handle(new ConfirmFormCommand { CaseInstanceId = id, CaseElementInstanceId = elt });
return new OkResult();
}

[HttpGet("{id}")]
public async Task<IActionResult> Get(string id)
{
return null;
var flowInstance = await _processFlowInstanceQueryRepository.FindFlowInstanceById(id);
if (flowInstance == null)
{
return new NotFoundResult();
}

return new OkObjectResult(ToDto(flowInstance));
}

private static JObject ToDto(ProcessFlowInstance flowInstance)
{
var result = new JObject
{
{ "id", flowInstance.Id },
{ "create_datetime", flowInstance.CreateDateTime },
{ "status", Enum.GetName(typeof(ProcessFlowInstanceStatus), flowInstance.Status).ToLowerInvariant() }
};
var planItems = new JArray();
foreach(var planItem in flowInstance.Elements.Where(e => e is CMMNPlanItem).Cast<CMMNPlanItem>())
{
planItems.Add(ToDto(planItem));
}

result.Add("items", planItems);
return result;
}

private static JObject ToDto(CMMNPlanItem planItem)
{
return new JObject
{
{ "id", planItem.Id },
{ "name", planItem.Name },
{ "status", Enum.GetName(typeof(ProcessFlowInstanceElementStatus), planItem.Status).ToLowerInvariant() }
};
}
}
}
}
15 changes: 14 additions & 1 deletion src/CaseManagement.CMMN/ApplicationBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
namespace Microsoft.AspNetCore.Builder
using CaseManagement.CMMN.CaseInstance.EventHandlers;
using CaseManagement.Workflow.Domains.Events;
using CaseManagement.Workflow.Infrastructure.EvtBus;

namespace Microsoft.AspNetCore.Builder
{
public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseCMMN(this IApplicationBuilder appBuilder)
{
appBuilder.ConfigureEventBus();
appBuilder.UseMvc();
return appBuilder;
}

private static void ConfigureEventBus(this IApplicationBuilder app)
{
var evtBus = (IEventBus)app.ApplicationServices.GetService(typeof(IEventBus));
evtBus.Subscribe<ProcessFlowInstanceCreatedEvent, ProcessFlowInstanceCreatedEventHandler>();
evtBus.Subscribe<ProcessFlowInstanceLaunchedEvent, ProcessFlowInstanceLaunchedEventHandler>();
evtBus.Subscribe<ProcessFlowInstanceFormConfirmedEvent, ProcessFlowInstanceFormConfirmedEventHandler>();
}
}
}
14 changes: 5 additions & 9 deletions src/CaseManagement.CMMN/CMMNServerBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
using CaseManagement.CMMN.Persistence;
using CaseManagement.CMMN.Persistence.InMemory;
using CaseManagement.Workflow;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;

namespace CaseManagement.CMMN
{
public class CMMNServerBuilder
public class CMMNServerBuilder : WorkflowServerBuilder
{
private readonly IServiceCollection _services;

public CMMNServerBuilder(IServiceCollection services)
{
_services = services;
}
public CMMNServerBuilder(IServiceCollection services) : base(services) { }

public CMMNServerBuilder AddDefinitions(Action<CMMNDefinitionsBuilder> callback)
{
var builder = new CMMNDefinitionsBuilder();
callback(builder);
_services.AddSingleton<ICMMNDefinitionsQueryRepository>(new InMemoryCMMNDefinitionsQueryRepository(builder.Build()));
Services.AddSingleton<ICMMNDefinitionsQueryRepository>(new InMemoryCMMNDefinitionsQueryRepository(builder.Build()));
return this;
}

public CMMNServerBuilder AddDefinitions(ICollection<tDefinitions> defs)
{
_services.AddSingleton<ICMMNDefinitionsQueryRepository>(new InMemoryCMMNDefinitionsQueryRepository(defs));
Services.AddSingleton<ICMMNDefinitionsQueryRepository>(new InMemoryCMMNDefinitionsQueryRepository(defs));
return this;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using CaseManagement.CMMN.Domains;
using CaseManagement.Workflow.Domains;
using CaseManagement.Workflow.Infrastructure.EvtBus;
using CaseManagement.Workflow.Infrastructure.EvtStore;
using Microsoft.Extensions.Options;
using NEventStore;
using System.Linq;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public class ConfirmFormCommandHandler : BaseCommandHandler<ProcessFlowInstance>, IConfirmFormCommandHandler
{
private readonly IEventStoreRepository<ProcessFlowInstance> _eventStoreRepository;

public ConfirmFormCommandHandler(IStoreEvents storeEvents, IEventBus eventBus, IEventStoreRepository<ProcessFlowInstance> eventStoreRepository, IAggregateSnapshotStore<ProcessFlowInstance> aggregateSnapshotStore, IOptions<SnapshotConfiguration> snapshotConfiguration) : base(storeEvents, eventBus, aggregateSnapshotStore, snapshotConfiguration)
{
_eventStoreRepository = eventStoreRepository;
}

public async Task<bool> Handle(ConfirmFormCommand confirmFormCommand)
{
var caseInstance = await _eventStoreRepository.GetLastAggregate(confirmFormCommand.CaseInstanceId, ProcessFlowInstance.GetStreamName(confirmFormCommand.CaseInstanceId));
if (caseInstance == null || string.IsNullOrWhiteSpace(caseInstance.Id))
{
// TODO : THROW EXCEPTION.
}

var flowInstanceElt = caseInstance.Elements.FirstOrDefault(e => e.Id == confirmFormCommand.CaseElementInstanceId) as CMMNPlanItem;
if (flowInstanceElt == null)
{
// TODO : THROW EXCEPTION.
}

caseInstance.ConfirmForm(confirmFormCommand.CaseElementInstanceId);
await Commit(caseInstance, caseInstance.GetStreamName());
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@
using CaseManagement.CMMN.Persistence;
using CaseManagement.Workflow.Builders;
using CaseManagement.Workflow.Domains;
using CaseManagement.Workflow.Persistence;
using CaseManagement.Workflow.Infrastructure.EvtBus;
using CaseManagement.Workflow.Infrastructure.EvtStore;
using Microsoft.Extensions.Options;
using NEventStore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.Handlers
namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public class CreateCaseInstanceCommandHandler : ICreateCaseInstanceCommandHandler
public class CreateCaseInstanceCommandHandler : BaseCommandHandler<ProcessFlowInstance>, ICreateCaseInstanceCommandHandler
{
private readonly ICMMNDefinitionsQueryRepository _cmmnDefinitionsQueryRepository;
private readonly IProcessFlowInstanceCommandRepository _processFlowInstanceCommandRepository;

public CreateCaseInstanceCommandHandler(ICMMNDefinitionsQueryRepository cmmnDefinitionsQueryRepository, IProcessFlowInstanceCommandRepository processFlowInstanceCommandRepository)
public CreateCaseInstanceCommandHandler(ICMMNDefinitionsQueryRepository cmmnDefinitionsQueryRepository, IStoreEvents storeEvents, IEventBus eventBus, IAggregateSnapshotStore<ProcessFlowInstance> aggregateSnapshotStore,IOptions<SnapshotConfiguration> snapshotConfiguration) : base(storeEvents, eventBus, aggregateSnapshotStore, snapshotConfiguration)
{
_cmmnDefinitionsQueryRepository = cmmnDefinitionsQueryRepository;
_processFlowInstanceCommandRepository = processFlowInstanceCommandRepository;
}

public async Task<string> Handle(CreateCaseInstanceCommand createCaseInstanceCommand)
Expand All @@ -39,8 +40,7 @@ public async Task<string> Handle(CreateCaseInstanceCommand createCaseInstanceCom
}

var processFlowInstance = BuildProcessFlowInstance(tCase);
_processFlowInstanceCommandRepository.Add(processFlowInstance);
await _processFlowInstanceCommandRepository.SaveChanges();
await Commit(processFlowInstance, processFlowInstance.GetStreamName());
return processFlowInstance.Id;
}

Expand Down Expand Up @@ -102,12 +102,12 @@ private static CMMNPlanItemDefinition BuildPlanItemDefinition(tPlanItemDefinitio

private static CMMNPlanItemDefinition BuildProcessTask(tProcessTask processTask)
{
return new CMMNProcessTask(processTask.name);
return new CMMNProcessTask(processTask.name) { AssemblyQualifiedName = processTask.assemblyQualifiedName, IsBlocking = processTask.isBlocking };
}

private static CMMNPlanItemDefinition BuildHumanTask(tHumanTask humanTask)
{
return new CMMNHumanTask(humanTask.name);
return new CMMNHumanTask(humanTask.name) { FormId = humanTask.caseFormRef, IsBlocking = humanTask.isBlocking };
}

private static CMMNSEntry BuildSEntry(tSentry sEntry)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public interface IConfirmFormCommandHandler
{
Task<bool> Handle(ConfirmFormCommand confirmFormCommand);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.Handlers
namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public interface ICreateCaseInstanceCommandHandler
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.Handlers
namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public interface ILaunchCaseInstanceCommandHandler
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using CaseManagement.CMMN.CaseInstance.Commands;
using CaseManagement.Workflow.Domains;
using CaseManagement.Workflow.Infrastructure.EvtBus;
using CaseManagement.Workflow.Infrastructure.EvtStore;
using Microsoft.Extensions.Options;
using NEventStore;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.CommandHandlers
{
public class LaunchCaseInstanceCommandHandler : BaseCommandHandler<ProcessFlowInstance>, ILaunchCaseInstanceCommandHandler
{
private readonly IEventStoreRepository<ProcessFlowInstance> _eventStoreRepository;

public LaunchCaseInstanceCommandHandler(IStoreEvents storeEvents, IEventBus eventBus, IEventStoreRepository<ProcessFlowInstance> eventStoreRepository, IAggregateSnapshotStore<ProcessFlowInstance> aggregateSnapshotStore, IOptions<SnapshotConfiguration> snapshotConfiguration) : base(storeEvents, eventBus, aggregateSnapshotStore, snapshotConfiguration)
{
_eventStoreRepository = eventStoreRepository;
}

public async Task Handle(LaunchCaseInstanceCommand launchCaseInstanceCommand)
{
var caseInstance = await _eventStoreRepository.GetLastAggregate(launchCaseInstanceCommand.CaseInstanceId, ProcessFlowInstance.GetStreamName(launchCaseInstanceCommand.CaseInstanceId));
if (caseInstance == null || string.IsNullOrWhiteSpace(caseInstance.Id))
{
// TODO : THROW EXCEPTION.
}


caseInstance.Launch();
await Commit(caseInstance, caseInstance.GetStreamName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Runtime.Serialization;

namespace CaseManagement.CMMN.CaseInstance.Commands
{
[DataContract]
public class ConfirmFormCommand
{
public string CaseInstanceId { get; set; }
public string CaseElementInstanceId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using CaseManagement.Workflow.Domains;
using CaseManagement.Workflow.Domains.Events;
using CaseManagement.Workflow.Infrastructure;
using CaseManagement.Workflow.Infrastructure.EvtBus;
using CaseManagement.Workflow.Persistence;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace CaseManagement.CMMN.CaseInstance.EventHandlers
{
public class ProcessFlowInstanceCreatedEventHandler : IDomainEventHandler<ProcessFlowInstanceCreatedEvent>
{
private readonly IProcessFlowInstanceCommandRepository _processFlowInstanceCommandRepository;

public ProcessFlowInstanceCreatedEventHandler(IProcessFlowInstanceCommandRepository processFlowInstanceCommandRepository)
{
_processFlowInstanceCommandRepository = processFlowInstanceCommandRepository;
}

public async Task Handle(ProcessFlowInstanceCreatedEvent @event)
{
var processFlowInstance = ProcessFlowInstance.New(new List<DomainEvent> { @event });
_processFlowInstanceCommandRepository.Add(processFlowInstance);
await _processFlowInstanceCommandRepository.SaveChanges();
}
}
}
Loading

0 comments on commit 630243a

Please sign in to comment.