Changeset 71:da2aa3a01791

Tidied up and renamed projects
author unexist
date Mon, 16 Aug 2021 17:33:16 +0200
parents a65d7d855602
children 4013ae5abb81
files todo-service-camunda-quarkus/pom.xml todo-service-camunda-quarkus/src/main/docker/Dockerfile.fast-jar todo-service-camunda-quarkus/src/main/docker/Dockerfile.jvm todo-service-camunda-quarkus/src/main/docker/Dockerfile.native todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java todo-service-camunda-quarkus/src/main/resources/META-INF/resources/index.html todo-service-camunda-quarkus/src/main/resources/META-INF/resources/todo.bpmn todo-service-camunda-quarkus/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider todo-service-camunda-quarkus/src/main/resources/application.properties todo-service-camunda-quarkus/src/main/resources/todo.bpmn todo-service-camunda-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java todo-service-camunda-rest-engine-quarkus/pom.xml todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.fast-jar todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.jvm todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.native todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java todo-service-camunda-rest-engine-quarkus/src/main/resources/META-INF/resources/index.html todo-service-camunda-rest-engine-quarkus/src/main/resources/META-INF/resources/todo.bpmn todo-service-camunda-rest-engine-quarkus/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider todo-service-camunda-rest-engine-quarkus/src/main/resources/application.properties todo-service-camunda-rest-engine-quarkus/src/main/resources/todo.bpmn todo-service-camunda-rest-engine-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java todo-service-camunda/pom.xml todo-service-camunda/src/main/docker/Dockerfile.fast-jar todo-service-camunda/src/main/docker/Dockerfile.jvm todo-service-camunda/src/main/docker/Dockerfile.native todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java todo-service-camunda/src/main/resources/META-INF/resources/index.html todo-service-camunda/src/main/resources/META-INF/resources/todo.bpmn todo-service-camunda/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider todo-service-camunda/src/main/resources/application.properties todo-service-camunda/src/main/resources/todo.bpmn todo-service-camunda/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java todo-service-kogito-quarkus/pom.xml todo-service-kogito-quarkus/src/main/docker/Dockerfile.fast-jar todo-service-kogito-quarkus/src/main/docker/Dockerfile.jvm todo-service-kogito-quarkus/src/main/docker/Dockerfile.native todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/application/KogitoService.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java todo-service-kogito-quarkus/src/main/resources/META-INF/resources/index.html todo-service-kogito-quarkus/src/main/resources/application.properties todo-service-kogito-quarkus/src/main/resources/dev/unexist/showcase/todo/todo.bpmn todo-service-kogito-quarkus/src/main/resources/dev/unexist/showcase/todo/todo.drl todo-service-kogito-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java
diffstat 88 files changed, 5194 insertions(+), 1657 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/pom.xml	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>todo-service-camunda-quarkus</artifactId>
+    <version>0.1</version>
+
+    <parent>
+        <groupId>dev.unexist.showcase</groupId>
+        <artifactId>showcase-workflow-quarkus</artifactId>
+        <version>0.1</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <properties>
+        <camunda-bom.version>7.15.0</camunda-bom.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.camunda.bpm</groupId>
+                <artifactId>camunda-bom</artifactId>
+                <version>${camunda-bom.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <!-- Quarkus -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-container-image-jib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jdbc-h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-agroal</artifactId>
+        </dependency>
+
+        <!-- Camunda -->
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-cdi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-rest</artifactId>
+            <classifier>classes</classifier>
+        </dependency>
+
+        <!-- Camunda JSON/XML handling -->
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-plugin-spin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.spin</groupId>
+            <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr353</artifactId>
+        </dependency>
+    </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/docker/Dockerfile.fast-jar	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,57 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/quarkus-kubernetes-showcase-fast-jar .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
+COPY --chown=1001 target/quarkus-app/*.jar /deployments/
+COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
+COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/docker/Dockerfile.jvm	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,54 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-kubernetes-showcase-jvm .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-jvm
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-jvm
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+COPY target/lib/* /deployments/lib/
+COPY target/*-runner.jar /deployments/app.jar
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/docker/Dockerfile.native	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,27 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
+#
+# Before building the container image run:
+#
+# mvn package -Pnative -Dquarkus.native.container-build=true
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-kubernetes-showcase .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+WORKDIR /work/
+RUN chown 1001 /work \
+    && chmod "g+rwX" /work \
+    && chown 1001:root /work
+COPY --chown=1001:root target/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,74 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda resource
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.camunda.bpm.engine.variable.Variables;
+import org.camunda.bpm.engine.variable.value.ObjectValue;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+import org.eclipse.microprofile.openapi.annotations.tags.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+
+@Path("/camunda")
+public class CamundaResource {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaResource.class);
+
+    @Inject
+    CamundaEngine camundaEngine;
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Create new todo")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "201", description = "Todo created"),
+            @APIResponse(responseCode = "406", description = "Bad data"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response create(TodoBase base, @Context UriInfo info) {
+        ProcessEngine ProcEngine = this.camundaEngine.getProcessEngine();
+
+        ObjectValue todoAsJson = Variables.objectValue(base)
+                        .serializationDataFormat("application/json").create();
+
+        ProcessInstance processInstance = ProcEngine.getRuntimeService()
+                .createProcessInstanceByKey("todo")
+                .setVariable("todo", todoAsJson)
+                .executeWithVariablesInReturn();
+
+        String id = processInstance.getId();
+
+        URI uri = info.getAbsolutePathBuilder().path("/" + id).build();
+
+        LOGGER.info("Process {} started", id);
+
+        return Response.created(uri).build();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,157 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo resource
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
+import org.eclipse.microprofile.openapi.annotations.media.Content;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+import org.eclipse.microprofile.openapi.annotations.tags.Tag;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/todo")
+public class TodoResource {
+
+    @Inject
+    TodoService todoService;
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Create new todo")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "201", description = "Todo created"),
+            @APIResponse(responseCode = "406", description = "Bad data"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response create(TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.create(base)) {
+            response = Response.status(Response.Status.CREATED);
+        } else {
+            response = Response.status(Response.Status.NOT_ACCEPTABLE);
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get all todos")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "List of todo", content =
+                @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = Todo.class))),
+            @APIResponse(responseCode = "204", description = "Nothing found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response getAll() {
+        List<Todo> todoList = this.todoService.getAll();
+
+        Response.ResponseBuilder response;
+
+        if (todoList.isEmpty()) {
+            response = Response.noContent();
+        } else {
+            response = Response.ok(Entity.json(todoList));
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "Todo found", content =
+                @Content(schema = @Schema(implementation = Todo.class))),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response findById(@PathParam("id") int id) {
+        Optional<Todo> result = this.todoService.findById(id);
+
+        Response.ResponseBuilder response;
+
+        if (result.isPresent()) {
+            response = Response.ok(Entity.json(result.get()));
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Update todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "204", description = "Todo updated"),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response update(@PathParam("id") int id, TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.update(id, base)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @DELETE
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Delete todo by id")
+    @Tag(name = "Todo")
+    public Response delete(@PathParam("id") int id) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.delete(id)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,42 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda todo check task
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter.tasks;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.camunda.bpm.engine.variable.VariableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Dependent
+@Named
+public class CamundaTodoCheckTask implements JavaDelegate {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoCheckTask.class);
+
+    @Inject
+    TodoService todoService;
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        VariableMap varMap = execution.getVariablesTyped();
+
+        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
+
+        LOGGER.info("Todo check task: {}, total: {}", todo, this.todoService);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,37 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda todo tally task
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter.tasks;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.camunda.bpm.engine.variable.VariableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Named;
+
+@Dependent
+@Named
+public class CamundaTodoTallyTask implements JavaDelegate {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoTallyTask.class);
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        VariableMap varMap = execution.getVariablesTyped();
+
+        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
+
+        LOGGER.info("Todo tally task: {}", todo);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,48 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo application
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import dev.unexist.showcase.todo.adapter.CamundaResource;
+import dev.unexist.showcase.todo.adapter.TodoResource;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
+import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
+import org.camunda.bpm.engine.rest.impl.CamundaRestResources;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class RestApplication extends Application {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+
+        /* Add your own classes */
+        classes.add(TodoResource.class);
+        classes.add(CamundaResource.class);
+        classes.add(CamundaEngine.class);
+
+        /* Add tasks */
+        classes.add(CamundaTodoCheckTask.class);
+        classes.add(CamundaTodoTallyTask.class);
+
+        /* Add all camunda engine rest resources (or just add those that you actually need) */
+        classes.addAll(CamundaRestResources.getResourceClasses());
+
+        /* Mandatory */
+        classes.addAll(CamundaRestResources.getConfigurationClasses());
+
+        return classes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,67 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file DueDate class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import dev.unexist.showcase.todo.infrastructure.serializer.DateSerializer;
+
+import java.time.LocalDate;
+
+public class DueDate {
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate start;
+
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate due;
+
+    /**
+     * Get start date
+     *
+     * @return Start date
+     **/
+
+    public LocalDate getStart() {
+        return start;
+    }
+
+    /**
+     * Set start date
+     *
+     * @param start
+     *         Date to set
+     **/
+
+    public void setStart(LocalDate start) {
+        this.start = start;
+    }
+
+    /**
+     * Get due date
+     *
+     * @return Due date
+     **/
+
+    public LocalDate getDue() {
+        return due;
+    }
+
+    /**
+     * Set due date
+     *
+     * @param due
+     *         Date to set
+     **/
+
+    public void setDue(LocalDate due) {
+        this.due = due;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo class and aggregate root
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+public class Todo extends TodoBase {
+    private int id;
+
+    /**
+     * Constructor
+     **/
+
+    public Todo() {
+    }
+
+    /**
+     * Constructor
+     *
+     * @param  base  Base entry
+     **/
+
+    public Todo(final TodoBase base) {
+        this.update(base);
+    }
+
+    /**
+     * Update values from base
+     *
+     * @param  base  Todo base class
+     **/
+
+    public void update(final TodoBase base) {
+        this.setDueDate(base.getDueDate());
+        this.setTitle(base.getTitle());
+        this.setDescription(base.getDescription());
+        this.setDone(base.getDone());
+    }
+
+    /**
+     * Get id of entry
+     *
+     * @return Id of the entry
+     **/
+
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Set id of entry
+     *
+     * @param  id  Id of the entry
+     **/
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,117 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo base class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Objects;
+
+public class TodoBase {
+
+    @NotBlank
+    private String title;
+
+    @NotBlank
+    private String description;
+
+    private Boolean done;
+
+    @NotNull
+    private DueDate dueDate;
+
+    /**
+     * Get title of the entry
+     *
+     * @return Title of the entry
+     **/
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Set title of the entry
+     *
+     * @param  title  Title of the entry
+     **/
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * Get description of entry
+     *
+     * @return Description of the entry
+     **/
+
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set description of the entry
+     *
+     * @param description
+     *          Description of the entry
+     **/
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * Get done state of entry
+     *
+     * @return Done state of the entry
+     **/
+
+    public Boolean getDone() {
+        return done;
+    }
+
+    /**
+     * Set done state of entry
+     *
+     * @param  done  Done state of the entry
+     **/
+
+    public void setDone(Boolean done) {
+        this.done = done;
+    }
+
+    /**
+     * Get due state of the entry
+     *
+     * @return Due state of the entry
+     **/
+
+    public DueDate getDueDate() {
+        return dueDate;
+    }
+
+    /**
+     * Set due date of the entry
+     *
+     * @param  dueDate  Due date of the entry
+     **/
+
+    public void setDueDate(DueDate dueDate) {
+        Objects.requireNonNull(dueDate, "DueDate cannot be null");
+
+        this.dueDate = dueDate;
+
+        if (null != dueDate.getStart() && null != dueDate.getDue()) {
+            this.done = dueDate.getStart().isBefore(dueDate.getDue());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository interface
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface TodoRepository {
+
+    /**
+     * Add {@link Todo} entry to list
+     *
+     * @param  todo  {@link Todo} entry to add
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean add(Todo todo);
+
+    /**
+     * Update {@link Todo} with given id
+     *
+     * @param  todo  A {@link Todo} to update
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean update(Todo todo);
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean deleteById(int id);
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all stored {@link Todo}
+     **/
+
+    List<Todo> getAll();
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to find
+     *
+     * @return A {@link Optional} with the result of the lookup
+     **/
+
+    Optional<Todo> findById(int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,94 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo service and domain service
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class TodoService {
+
+    @Inject
+    TodoRepository todoRepository;
+
+    /**
+     * Create new {@link Todo} entry and store it in repository
+     *
+     * @param  base  A {@link TodoBase} entry
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean create(TodoBase base) {
+        Todo todo = new Todo(base);
+
+        return this.todoRepository.add(todo);
+    }
+
+    /**
+     * Update {@link Todo} at with given id
+     *
+     * @param  id    Id to update
+     * @param  base  Values for the entry
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean update(int id, TodoBase base) {
+        Optional<Todo> todo = this.findById(id);
+        boolean ret = false;
+
+        if (todo.isPresent()) {
+            todo.get().update(base);
+
+            ret = this.todoRepository.update(todo.get());
+        }
+
+        return ret;
+    }
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean delete(int id) {
+        return this.todoRepository.deleteById(id);
+    }
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all {@link Todo}; might be empty
+     **/
+
+    public List<Todo> getAll() {
+        return this.todoRepository.getAll();
+    }
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to look for
+     *
+     * @return A {@link Optional} of the entry
+     **/
+
+    public Optional<Todo> findById(int id) {
+        return this.todoRepository.findById(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,127 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda engine helper
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.camunda;
+
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
+import io.agroal.api.AgroalDataSource;
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.ProcessEngineConfiguration;
+import org.camunda.bpm.engine.RepositoryService;
+import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
+import org.camunda.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration;
+import org.camunda.bpm.engine.repository.ProcessDefinition;
+import org.camunda.bpm.model.bpmn.Bpmn;
+import org.camunda.bpm.model.bpmn.BpmnModelInstance;
+import org.camunda.spin.plugin.impl.SpinProcessEnginePlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.sql.DataSource;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+@ApplicationScoped
+public class CamundaEngine {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaEngine.class);
+
+    private ProcessEngine processEngine;
+
+    @Inject
+    AgroalDataSource defaultDataSource;
+
+    /**
+     * Get process engine
+     *
+     * @return Either newly created {@link ProcessEngine} or from cache
+     **/
+
+    public ProcessEngine getProcessEngine() {
+        if (null == this.processEngine) {
+            this.createProcessEngineWithDataSource(this.defaultDataSource);
+            this.deployProcess();
+        }
+
+        return this.processEngine;
+    }
+
+    /**
+     * Create new engine with given {@link DataSource}
+     *
+     * @param  dataSource  A {@link DataSource}
+     **/
+
+    private void createProcessEngineWithDataSource(DataSource dataSource) {
+        try {
+            StandaloneProcessEngineConfiguration config =
+                    new StandaloneProcessEngineConfiguration();
+
+            List<ProcessEnginePlugin> pluginList = List.of(new SpinProcessEnginePlugin());
+
+            /* Provide list of beans */
+            Map<Object, Object> beanList = Map.of(
+                    ClassUtils.getShortNameAsProperty(CamundaTodoCheckTask.class),
+                        CamundaTodoCheckTask.class,
+                    ClassUtils.getShortNameAsProperty(CamundaTodoTallyTask.class),
+                        CamundaTodoTallyTask.class
+            );
+
+            config.setDataSource(dataSource);
+            config.setDatabaseSchemaUpdate(
+                    ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
+            config.setJobExecutorActivate(true);
+            config.setProcessEnginePlugins(pluginList);
+            config.setBeans(beanList);
+
+            this.processEngine = config.buildProcessEngine();
+        } catch (Exception e) {
+            LOGGER.error("getProcessEngine", e);
+        }
+    }
+
+    /**
+     * Deploy process on cached engine
+     **/
+
+    private void deployProcess() {
+        RepositoryService repositoryService =
+                this.processEngine.getRepositoryService();
+
+        try {
+            ProcessDefinition process = repositoryService.createProcessDefinitionQuery()
+                    .processDefinitionKey("todo")
+                    .latestVersion()
+                    .singleResult();
+
+            if (null == process) {
+                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+                InputStream inputStream = classLoader.getResourceAsStream("todo.bpmn");
+
+                BpmnModelInstance todoInstance = Bpmn.readModelFromStream(inputStream);
+                repositoryService.createDeployment()
+                        .addModelInstance("todo.bpmn", todoInstance)
+                        .deploy();
+
+                LOGGER.info("Process definition inputStream deployed");
+            } else {
+                LOGGER.info("Process definition is activated");
+            }
+        } catch (RuntimeException e) {
+            LOGGER.error("deployProcesses", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,61 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda engine provider
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.camunda;
+
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.rest.spi.ProcessEngineProvider;
+
+import javax.inject.Inject;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CamundaEngineProvider implements ProcessEngineProvider {
+
+    @Inject
+    CamundaEngine camundaEngine;
+
+    /**
+     * Get default process engine via SPI
+     *
+     * @return Default {@link ProcessEngine}
+     **/
+
+    public ProcessEngine getDefaultProcessEngine() {
+        return this.camundaEngine.getProcessEngine();
+    }
+
+    /**
+     * Get process engine by name
+     *
+     * @param  name  Name of the engine
+     *
+     * @return Found {@link ProcessEngine}
+     **/
+
+    public ProcessEngine getProcessEngine(String name) {
+        return this.camundaEngine.getProcessEngine();
+    }
+
+    /**
+     * Get list of all engine names
+     *
+     * @return List of known engine names
+     **/
+
+    public Set<String> getProcessEngineNames() {
+        Set<String> names = new HashSet<>();
+
+        names.add(this.camundaEngine.getProcessEngine().getName());
+
+        return names;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,87 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.persistence;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class ListTodoRepository implements TodoRepository {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ListTodoRepository.class);
+
+    private final List<Todo> list;
+
+    /**
+     * Constructor
+     **/
+
+    ListTodoRepository() {
+        this.list = new ArrayList<>();
+    }
+
+    @Override
+    public boolean add(final Todo todo) {
+        todo.setId(this.list.size() + 1);
+
+        return this.list.add(todo);
+    }
+
+    @Override
+    public boolean update(final Todo todo) {
+        boolean ret = false;
+
+        try {
+            this.list.set(todo.getId(), todo);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("update: id={} not found", todo.getId());
+        }
+
+        return ret;
+    }
+
+    @Override
+    public boolean deleteById(int id) {
+        boolean ret = false;
+
+        try {
+            this.list.remove(id);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("deleteById: id={} not found", id);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<Todo> getAll() {
+        return Collections.unmodifiableList(this.list);
+    }
+
+    @Override
+    public Optional<Todo> findById(int id) {
+        return this.list.stream()
+                .filter(t -> t.getId() == id)
+                .findFirst();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,39 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo serializer
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.serializer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class DateSerializer extends JsonSerializer<LocalDate> {
+    public static final String PATTERN = "yyyy-MM-dd";
+
+    /**
+     * Serialize {@link LocalDate} to format
+     *
+     * @param  value        Value to convert
+     * @param  gen          A {@link JsonGenerator}
+     * @param  serializers  A {@link SerializerProvider}
+     * @throws IOException
+     **/
+
+    @Override
+    public void serialize(LocalDate value, JsonGenerator gen,
+                          SerializerProvider serializers) throws IOException {
+        gen.writeString(value.format(DateTimeFormatter.ofPattern(PATTERN)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/resources/META-INF/resources/index.html	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,233 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>unexist.dev</title>
+    <style type="text/css">
+        :root {
+            /* Colors */
+            --font-color: #fff;
+            --font-color2: #aaa;
+            --link-color: #8cf;
+            --highlight-color: #ff8000;
+            --border-color: #446979;
+            --top-color: #313536;
+            --bottom-color: #1D2021;
+            --h1-color: #888;
+            --h2-color: #777;
+            --h3-color: #666;
+            --h4-color: #d7ba7d;
+            --code-color: #d7ba7d;
+            --cite-color: #777;
+
+            /* Misc */
+            --margin: 10px;
+            --padding: 10px;
+            --radius: 8px;
+            --border: 1px solid var(--top-color);
+        }
+
+        * {
+            margin: 0px;
+            padding: 0px;
+        }
+
+        /* Layout */
+        body {
+            background-color: var(--bottom-color);
+            color: var(--font-color);
+            font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,sans-serif;
+        }
+
+        nav {
+            background-color: var(--bottom-color);
+            border-radius: var(--radius) var(--radius) 0px 0px;
+            font-size: 90%;
+        }
+
+        footer {
+            color: var(--font-color2);
+            background-color: var(--top-color);
+            border-left: var(--border);
+            border-right: var(--border);
+            border-bottom: var(--border);
+            border-radius: 0px 0px var(--radius) var(--radius);
+            font-size: 70%;
+            text-align: center;
+        }
+
+        footer a:link, footer a:visited {
+            color: var(--font-color2);
+            text-decoration: underline;
+        }
+
+        footer a:hover {
+            color: var(--link-color);
+            text-decoration: none;
+        }
+
+        #container {
+            width: 100%;
+        }
+
+        #split {
+            display: table;
+            padding-top: var(--padding);
+            border-left: var(--border);
+            border-right: var(--border);
+        }
+
+        #content {
+            display: table-cell;
+            padding-right: var(--padding);
+        }
+
+        #content h1 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+            margin-bottom: 10px;
+        }
+
+        #content h2 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+            margin-bottom: 10px;
+        }
+
+        #sidebar a {
+            display: block;
+        }
+
+        #header {
+            background-color: var(--top-color);
+            width: 100%;
+        }
+
+        #headline, #split, nav, footer {
+            width: 70%;
+            margin: 0px auto;
+            padding: var(--padding);
+
+            /* Stupid hack */
+            min-width: 844px;
+        }
+
+        @media screen and (max-width: 899px) {
+            #headline, #split, nav, footer {
+                width: 100%;
+            }
+        }
+
+        #headline h1 {
+            display: inline-block;
+            text-decoration: none;
+            border-bottom: none;
+        }
+
+        #headline h2 {
+            display: inline-block;
+            padding-left: var(--padding);
+            border-bottom: none;
+        }
+
+        /* Text */
+        a:link, a:visited {
+            text-decoration: none;
+            color: var(--link-color);
+        }
+
+        a:hover {
+            color: var(--highlight-color);
+        }
+
+        h1 {
+            color: var(--h1-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+        }
+
+        h2 {
+            color: var(--h2-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+        }
+
+        h3 {
+            color: var(--h3-color);
+            text-decoration: underline;
+            display: inline;
+        }
+
+        h3, h4 {
+            padding-top: 10px;
+        }
+
+        h4 {
+            color: var(--h4-color);
+        }
+
+        .post-content li {
+            margin-left: 40px;
+            padding: 0px 0px var(--padding) 0px;
+            color: var(--font-color2);
+        }
+    </style>
+</head>
+<body>
+<div id="container">
+    <div id="header">
+        <div id="headline">
+            <h1>unexist.dev</h1>
+            <h2></h2>
+            <h2></h2>
+            <p>Showcase for @project.artifactId@</p>
+        </div>
+        <nav>
+            <a href="/">Home</a>
+            <a href="https://unexist.dev">Projects</a>
+            <a href="https://hg.unexist.dev">Repositories</a>
+        </nav>
+    </div>
+    <div id="split">
+        <div id="content">
+            <div id="posts">
+                <h2>Information</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li>
+                            <h3>Group</h3>: @project.groupId@
+                        </li>
+                        <li>
+                            <h3>Artifact</h3>: @project.artifactId@
+                        </li>
+                        <li>
+                            <h3>Version</h3>: @project.version@
+                        </li>
+                        <li>
+                            <h3>Build</h3> on @timestamp@ by @hg.author@
+                        </li>
+                    </ul>
+                </div>
+
+                <h2>Links</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li><a href="/q/dev">Developer console</a></li>
+                        <li><a href="/q/swagger-ui">Swagger UI</a></li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+    <footer>
+        <a href="/feed.xml">RSS</a>
+        &middot;
+        <a href="https://github.com/unexist">unexist @ GitHub</a>
+        &middot;
+        <a href="https://twitter.com/chkappel">unexist @ Twitter</a>
+    </footer>
+</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,1 @@
+dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngineProvider
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/resources/application.properties	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,38 @@
+# Configuration file
+# key = value
+#quarkus.swagger-ui.always-include=true
+#quarkus.servlet.context-path=/todo
+
+# Disable pass-though of infrastructure health
+#quarkus.datasource.health=false
+#quarkus.reactive-messaging.enabled=false
+#kafka.health.enabled=false
+
+# Opencontainers labels (https://github.com/opencontainers/image-spec/blob/master/annotations.md)
+quarkus.jib.labels."org.opencontainers.image.created"=@timestamp@
+quarkus.jib.labels."org.opencontainers.image.authors"=@hg.author@
+quarkus.jib.labels."org.opencontainers.image.url"=https://unexist.dev
+#quarkus.jib.labels."org.opencontainers.image.documentation"=DOCS
+#quarkus.jib.labels."org.opencontainers.image.source"=SRC
+quarkus.jib.labels."org.opencontainers.image.version"=@project.version@
+quarkus.jib.labels."org.opencontainers.image.revision"=@hg.rev@
+quarkus.jib.labels."org.opencontainers.image.licenses"=GPLv3
+quarkus.jib.labels."org.opencontainers.image.title"=@project.artifactId@
+quarkus.jib.labels."org.opencontainers.image.description"=@project.name@
+
+# OpenAPI3 specifications (https://quarkus.io/blog/openapi-for-everyone)
+mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@
+%dev.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [development]
+%test.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [test]
+mp.openapi.extensions.smallrye.info.version=@project.version@
+mp.openapi.extensions.smallrye.info.description=Last build on @timestamp@
+mp.openapi.extensions.smallrye.info.contact.email=christoph@unexist.dev
+mp.openapi.extensions.smallrye.info.contact.name=@hg.author@
+mp.openapi.extensions.smallrye.info.contact.url=https://unexist.dev
+mp.openapi.extensions.smallrye.info.license.name=Apache License v2.0
+mp.openapi.extensions.smallrye.info.license.url=https://www.apache.org/licenses/LICENSE-2.0
+
+# Database
+quarkus.datasource.db-kind=h2
+quarkus.datasource.username=username-default
+#quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/main/resources/todo.bpmn	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
+                  id="Definitions_0aui0ws" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler"
+                  exporterVersion="4.8.1">
+  <bpmn:process id="todo" name="Todo" isExecutable="true" camunda:versionTag="0.1">
+    <bpmn:startEvent id="StartEvent_1" name="Todo Retrieved">
+      <bpmn:outgoing>SequenceFlow_1p2szow</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:serviceTask id="Task_19pt1nu" name="Tally Todo " camunda:class="dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask">
+      <bpmn:incoming>SequenceFlow_04u8b2b</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1axd8hr</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:endEvent id="EndEvent_1oyw02k" name="Todo Done">
+      <bpmn:incoming>SequenceFlow_1axd8hr</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1axd8hr" sourceRef="Task_19pt1nu" targetRef="EndEvent_1oyw02k" />
+    <bpmn:serviceTask id="Task_0q4zvgp" name="Check Todo" camunda:delegateExpression="${camundaTodoCheckTask}">
+      <bpmn:incoming>SequenceFlow_1p2szow</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_04u8b2b</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="SequenceFlow_1p2szow" sourceRef="StartEvent_1" targetRef="Task_0q4zvgp" />
+    <bpmn:sequenceFlow id="SequenceFlow_04u8b2b" sourceRef="Task_0q4zvgp" targetRef="Task_19pt1nu" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="todo">
+      <bpmndi:BPMNEdge id="SequenceFlow_04u8b2b_di" bpmnElement="SequenceFlow_04u8b2b">
+        <di:waypoint x="410" y="119" />
+        <di:waypoint x="480" y="119" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1p2szow_di" bpmnElement="SequenceFlow_1p2szow">
+        <di:waypoint x="200" y="119" />
+        <di:waypoint x="310" y="119" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1axd8hr_di" bpmnElement="SequenceFlow_1axd8hr">
+        <di:waypoint x="580" y="119" />
+        <di:waypoint x="662" y="119" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="345.5" y="98.5" width="90" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="164" y="101" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="145" y="137" width="74" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_17yjgnl_di" bpmnElement="Task_19pt1nu">
+        <dc:Bounds x="480" y="79" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_1oyw02k_di" bpmnElement="EndEvent_1oyw02k">
+        <dc:Bounds x="662" y="101" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="654" y="147" width="54" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1m8bv3v_di" bpmnElement="Task_0q4zvgp">
+        <dc:Bounds x="310" y="79" width="100" height="80" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,29 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Stupid integration test
+ * @copyright 2020-2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+
+@QuarkusTest
+public class TodoResourceTest {
+
+    @Test
+    public void testTodoEndpoint() {
+        given()
+          .when().get("/todo")
+          .then()
+             .statusCode(204);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/pom.xml	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>todo-service-camunda-rest-engine-quarkus</artifactId>
+    <version>0.1</version>
+
+    <parent>
+        <groupId>dev.unexist.showcase</groupId>
+        <artifactId>showcase-workflow-quarkus</artifactId>
+        <version>0.1</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <properties>
+        <camunda-bom.version>7.15.0</camunda-bom.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.camunda.bpm</groupId>
+                <artifactId>camunda-bom</artifactId>
+                <version>${camunda-bom.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <!-- Quarkus -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-container-image-jib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jdbc-h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-agroal</artifactId>
+        </dependency>
+
+        <!-- Camunda -->
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-cdi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-rest</artifactId>
+            <classifier>classes</classifier>
+        </dependency>
+
+        <!-- Camunda JSON/XML handling -->
+        <dependency>
+            <groupId>org.camunda.bpm</groupId>
+            <artifactId>camunda-engine-plugin-spin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.camunda.spin</groupId>
+            <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr353</artifactId>
+        </dependency>
+    </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.fast-jar	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,57 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/quarkus-kubernetes-showcase-fast-jar .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
+COPY --chown=1001 target/quarkus-app/*.jar /deployments/
+COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
+COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.jvm	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,54 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-kubernetes-showcase-jvm .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-jvm
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-jvm
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+COPY target/lib/* /deployments/lib/
+COPY target/*-runner.jar /deployments/app.jar
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/docker/Dockerfile.native	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,27 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
+#
+# Before building the container image run:
+#
+# mvn package -Pnative -Dquarkus.native.container-build=true
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-kubernetes-showcase .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+WORKDIR /work/
+RUN chown 1001 /work \
+    && chmod "g+rwX" /work \
+    && chown 1001:root /work
+COPY --chown=1001:root target/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,74 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda resource
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.camunda.bpm.engine.variable.Variables;
+import org.camunda.bpm.engine.variable.value.ObjectValue;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+import org.eclipse.microprofile.openapi.annotations.tags.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+
+@Path("/camunda")
+public class CamundaResource {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaResource.class);
+
+    @Inject
+    CamundaEngine camundaEngine;
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Create new todo")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "201", description = "Todo created"),
+            @APIResponse(responseCode = "406", description = "Bad data"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response create(TodoBase base, @Context UriInfo info) {
+        ProcessEngine ProcEngine = this.camundaEngine.getProcessEngine();
+
+        ObjectValue todoAsJson = Variables.objectValue(base)
+                        .serializationDataFormat("application/json").create();
+
+        ProcessInstance processInstance = ProcEngine.getRuntimeService()
+                .createProcessInstanceByKey("todo")
+                .setVariable("todo", todoAsJson)
+                .executeWithVariablesInReturn();
+
+        String id = processInstance.getId();
+
+        URI uri = info.getAbsolutePathBuilder().path("/" + id).build();
+
+        LOGGER.info("Process {} started", id);
+
+        return Response.created(uri).build();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,157 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo resource
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
+import org.eclipse.microprofile.openapi.annotations.media.Content;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+import org.eclipse.microprofile.openapi.annotations.tags.Tag;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/todo")
+public class TodoResource {
+
+    @Inject
+    TodoService todoService;
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Create new todo")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "201", description = "Todo created"),
+            @APIResponse(responseCode = "406", description = "Bad data"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response create(TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.create(base)) {
+            response = Response.status(Response.Status.CREATED);
+        } else {
+            response = Response.status(Response.Status.NOT_ACCEPTABLE);
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get all todos")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "List of todo", content =
+                @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = Todo.class))),
+            @APIResponse(responseCode = "204", description = "Nothing found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response getAll() {
+        List<Todo> todoList = this.todoService.getAll();
+
+        Response.ResponseBuilder response;
+
+        if (todoList.isEmpty()) {
+            response = Response.noContent();
+        } else {
+            response = Response.ok(Entity.json(todoList));
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "Todo found", content =
+                @Content(schema = @Schema(implementation = Todo.class))),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response findById(@PathParam("id") int id) {
+        Optional<Todo> result = this.todoService.findById(id);
+
+        Response.ResponseBuilder response;
+
+        if (result.isPresent()) {
+            response = Response.ok(Entity.json(result.get()));
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Update todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "204", description = "Todo updated"),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response update(@PathParam("id") int id, TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.update(id, base)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @DELETE
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Delete todo by id")
+    @Tag(name = "Todo")
+    public Response delete(@PathParam("id") int id) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.delete(id)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,42 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda todo check task
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter.tasks;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.camunda.bpm.engine.variable.VariableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Dependent
+@Named
+public class CamundaTodoCheckTask implements JavaDelegate {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoCheckTask.class);
+
+    @Inject
+    TodoService todoService;
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        VariableMap varMap = execution.getVariablesTyped();
+
+        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
+
+        LOGGER.info("Todo check task: {}, total: {}", todo, this.todoService);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,37 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda todo tally task
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter.tasks;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.camunda.bpm.engine.variable.VariableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.Dependent;
+import javax.inject.Named;
+
+@Dependent
+@Named
+public class CamundaTodoTallyTask implements JavaDelegate {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoTallyTask.class);
+
+    @Override
+    public void execute(DelegateExecution execution) throws Exception {
+        VariableMap varMap = execution.getVariablesTyped();
+
+        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
+
+        LOGGER.info("Todo tally task: {}", todo);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,48 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo application
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import dev.unexist.showcase.todo.adapter.CamundaResource;
+import dev.unexist.showcase.todo.adapter.TodoResource;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
+import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
+import org.camunda.bpm.engine.rest.impl.CamundaRestResources;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class RestApplication extends Application {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+
+        /* Add your own classes */
+        classes.add(TodoResource.class);
+        classes.add(CamundaResource.class);
+        classes.add(CamundaEngine.class);
+
+        /* Add tasks */
+        classes.add(CamundaTodoCheckTask.class);
+        classes.add(CamundaTodoTallyTask.class);
+
+        /* Add all camunda engine rest resources (or just add those that you actually need) */
+        classes.addAll(CamundaRestResources.getResourceClasses());
+
+        /* Mandatory */
+        classes.addAll(CamundaRestResources.getConfigurationClasses());
+
+        return classes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,67 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file DueDate class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import dev.unexist.showcase.todo.infrastructure.serializer.DateSerializer;
+
+import java.time.LocalDate;
+
+public class DueDate {
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate start;
+
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate due;
+
+    /**
+     * Get start date
+     *
+     * @return Start date
+     **/
+
+    public LocalDate getStart() {
+        return start;
+    }
+
+    /**
+     * Set start date
+     *
+     * @param start
+     *         Date to set
+     **/
+
+    public void setStart(LocalDate start) {
+        this.start = start;
+    }
+
+    /**
+     * Get due date
+     *
+     * @return Due date
+     **/
+
+    public LocalDate getDue() {
+        return due;
+    }
+
+    /**
+     * Set due date
+     *
+     * @param due
+     *         Date to set
+     **/
+
+    public void setDue(LocalDate due) {
+        this.due = due;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo class and aggregate root
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+public class Todo extends TodoBase {
+    private int id;
+
+    /**
+     * Constructor
+     **/
+
+    public Todo() {
+    }
+
+    /**
+     * Constructor
+     *
+     * @param  base  Base entry
+     **/
+
+    public Todo(final TodoBase base) {
+        this.update(base);
+    }
+
+    /**
+     * Update values from base
+     *
+     * @param  base  Todo base class
+     **/
+
+    public void update(final TodoBase base) {
+        this.setDueDate(base.getDueDate());
+        this.setTitle(base.getTitle());
+        this.setDescription(base.getDescription());
+        this.setDone(base.getDone());
+    }
+
+    /**
+     * Get id of entry
+     *
+     * @return Id of the entry
+     **/
+
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Set id of entry
+     *
+     * @param  id  Id of the entry
+     **/
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,117 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo base class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Objects;
+
+public class TodoBase {
+
+    @NotBlank
+    private String title;
+
+    @NotBlank
+    private String description;
+
+    private Boolean done;
+
+    @NotNull
+    private DueDate dueDate;
+
+    /**
+     * Get title of the entry
+     *
+     * @return Title of the entry
+     **/
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Set title of the entry
+     *
+     * @param  title  Title of the entry
+     **/
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * Get description of entry
+     *
+     * @return Description of the entry
+     **/
+
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set description of the entry
+     *
+     * @param description
+     *          Description of the entry
+     **/
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * Get done state of entry
+     *
+     * @return Done state of the entry
+     **/
+
+    public Boolean getDone() {
+        return done;
+    }
+
+    /**
+     * Set done state of entry
+     *
+     * @param  done  Done state of the entry
+     **/
+
+    public void setDone(Boolean done) {
+        this.done = done;
+    }
+
+    /**
+     * Get due state of the entry
+     *
+     * @return Due state of the entry
+     **/
+
+    public DueDate getDueDate() {
+        return dueDate;
+    }
+
+    /**
+     * Set due date of the entry
+     *
+     * @param  dueDate  Due date of the entry
+     **/
+
+    public void setDueDate(DueDate dueDate) {
+        Objects.requireNonNull(dueDate, "DueDate cannot be null");
+
+        this.dueDate = dueDate;
+
+        if (null != dueDate.getStart() && null != dueDate.getDue()) {
+            this.done = dueDate.getStart().isBefore(dueDate.getDue());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository interface
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface TodoRepository {
+
+    /**
+     * Add {@link Todo} entry to list
+     *
+     * @param  todo  {@link Todo} entry to add
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean add(Todo todo);
+
+    /**
+     * Update {@link Todo} with given id
+     *
+     * @param  todo  A {@link Todo} to update
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean update(Todo todo);
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean deleteById(int id);
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all stored {@link Todo}
+     **/
+
+    List<Todo> getAll();
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to find
+     *
+     * @return A {@link Optional} with the result of the lookup
+     **/
+
+    Optional<Todo> findById(int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,94 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo service and domain service
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class TodoService {
+
+    @Inject
+    TodoRepository todoRepository;
+
+    /**
+     * Create new {@link Todo} entry and store it in repository
+     *
+     * @param  base  A {@link TodoBase} entry
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean create(TodoBase base) {
+        Todo todo = new Todo(base);
+
+        return this.todoRepository.add(todo);
+    }
+
+    /**
+     * Update {@link Todo} at with given id
+     *
+     * @param  id    Id to update
+     * @param  base  Values for the entry
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean update(int id, TodoBase base) {
+        Optional<Todo> todo = this.findById(id);
+        boolean ret = false;
+
+        if (todo.isPresent()) {
+            todo.get().update(base);
+
+            ret = this.todoRepository.update(todo.get());
+        }
+
+        return ret;
+    }
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean delete(int id) {
+        return this.todoRepository.deleteById(id);
+    }
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all {@link Todo}; might be empty
+     **/
+
+    public List<Todo> getAll() {
+        return this.todoRepository.getAll();
+    }
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to look for
+     *
+     * @return A {@link Optional} of the entry
+     **/
+
+    public Optional<Todo> findById(int id) {
+        return this.todoRepository.findById(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,127 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda engine helper
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.camunda;
+
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
+import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
+import io.agroal.api.AgroalDataSource;
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.ProcessEngineConfiguration;
+import org.camunda.bpm.engine.RepositoryService;
+import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
+import org.camunda.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration;
+import org.camunda.bpm.engine.repository.ProcessDefinition;
+import org.camunda.bpm.model.bpmn.Bpmn;
+import org.camunda.bpm.model.bpmn.BpmnModelInstance;
+import org.camunda.spin.plugin.impl.SpinProcessEnginePlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.sql.DataSource;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+@ApplicationScoped
+public class CamundaEngine {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaEngine.class);
+
+    private ProcessEngine processEngine;
+
+    @Inject
+    AgroalDataSource defaultDataSource;
+
+    /**
+     * Get process engine
+     *
+     * @return Either newly created {@link ProcessEngine} or from cache
+     **/
+
+    public ProcessEngine getProcessEngine() {
+        if (null == this.processEngine) {
+            this.createProcessEngineWithDataSource(this.defaultDataSource);
+            this.deployProcess();
+        }
+
+        return this.processEngine;
+    }
+
+    /**
+     * Create new engine with given {@link DataSource}
+     *
+     * @param  dataSource  A {@link DataSource}
+     **/
+
+    private void createProcessEngineWithDataSource(DataSource dataSource) {
+        try {
+            StandaloneProcessEngineConfiguration config =
+                    new StandaloneProcessEngineConfiguration();
+
+            List<ProcessEnginePlugin> pluginList = List.of(new SpinProcessEnginePlugin());
+
+            /* Provide list of beans */
+            Map<Object, Object> beanList = Map.of(
+                    ClassUtils.getShortNameAsProperty(CamundaTodoCheckTask.class),
+                        CamundaTodoCheckTask.class,
+                    ClassUtils.getShortNameAsProperty(CamundaTodoTallyTask.class),
+                        CamundaTodoTallyTask.class
+            );
+
+            config.setDataSource(dataSource);
+            config.setDatabaseSchemaUpdate(
+                    ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
+            config.setJobExecutorActivate(true);
+            config.setProcessEnginePlugins(pluginList);
+            config.setBeans(beanList);
+
+            this.processEngine = config.buildProcessEngine();
+        } catch (Exception e) {
+            LOGGER.error("getProcessEngine", e);
+        }
+    }
+
+    /**
+     * Deploy process on cached engine
+     **/
+
+    private void deployProcess() {
+        RepositoryService repositoryService =
+                this.processEngine.getRepositoryService();
+
+        try {
+            ProcessDefinition process = repositoryService.createProcessDefinitionQuery()
+                    .processDefinitionKey("todo")
+                    .latestVersion()
+                    .singleResult();
+
+            if (null == process) {
+                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+                InputStream inputStream = classLoader.getResourceAsStream("todo.bpmn");
+
+                BpmnModelInstance todoInstance = Bpmn.readModelFromStream(inputStream);
+                repositoryService.createDeployment()
+                        .addModelInstance("todo.bpmn", todoInstance)
+                        .deploy();
+
+                LOGGER.info("Process definition inputStream deployed");
+            } else {
+                LOGGER.info("Process definition is activated");
+            }
+        } catch (RuntimeException e) {
+            LOGGER.error("deployProcesses", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,61 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Camunda engine provider
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.camunda;
+
+import org.camunda.bpm.engine.ProcessEngine;
+import org.camunda.bpm.engine.rest.spi.ProcessEngineProvider;
+
+import javax.inject.Inject;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CamundaEngineProvider implements ProcessEngineProvider {
+
+    @Inject
+    CamundaEngine camundaEngine;
+
+    /**
+     * Get default process engine via SPI
+     *
+     * @return Default {@link ProcessEngine}
+     **/
+
+    public ProcessEngine getDefaultProcessEngine() {
+        return this.camundaEngine.getProcessEngine();
+    }
+
+    /**
+     * Get process engine by name
+     *
+     * @param  name  Name of the engine
+     *
+     * @return Found {@link ProcessEngine}
+     **/
+
+    public ProcessEngine getProcessEngine(String name) {
+        return this.camundaEngine.getProcessEngine();
+    }
+
+    /**
+     * Get list of all engine names
+     *
+     * @return List of known engine names
+     **/
+
+    public Set<String> getProcessEngineNames() {
+        Set<String> names = new HashSet<>();
+
+        names.add(this.camundaEngine.getProcessEngine().getName());
+
+        return names;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,87 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.persistence;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class ListTodoRepository implements TodoRepository {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ListTodoRepository.class);
+
+    private final List<Todo> list;
+
+    /**
+     * Constructor
+     **/
+
+    ListTodoRepository() {
+        this.list = new ArrayList<>();
+    }
+
+    @Override
+    public boolean add(final Todo todo) {
+        todo.setId(this.list.size() + 1);
+
+        return this.list.add(todo);
+    }
+
+    @Override
+    public boolean update(final Todo todo) {
+        boolean ret = false;
+
+        try {
+            this.list.set(todo.getId(), todo);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("update: id={} not found", todo.getId());
+        }
+
+        return ret;
+    }
+
+    @Override
+    public boolean deleteById(int id) {
+        boolean ret = false;
+
+        try {
+            this.list.remove(id);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("deleteById: id={} not found", id);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<Todo> getAll() {
+        return Collections.unmodifiableList(this.list);
+    }
+
+    @Override
+    public Optional<Todo> findById(int id) {
+        return this.list.stream()
+                .filter(t -> t.getId() == id)
+                .findFirst();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,39 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo serializer
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.serializer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class DateSerializer extends JsonSerializer<LocalDate> {
+    public static final String PATTERN = "yyyy-MM-dd";
+
+    /**
+     * Serialize {@link LocalDate} to format
+     *
+     * @param  value        Value to convert
+     * @param  gen          A {@link JsonGenerator}
+     * @param  serializers  A {@link SerializerProvider}
+     * @throws IOException
+     **/
+
+    @Override
+    public void serialize(LocalDate value, JsonGenerator gen,
+                          SerializerProvider serializers) throws IOException {
+        gen.writeString(value.format(DateTimeFormatter.ofPattern(PATTERN)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/resources/META-INF/resources/index.html	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,233 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>unexist.dev</title>
+    <style type="text/css">
+        :root {
+            /* Colors */
+            --font-color: #fff;
+            --font-color2: #aaa;
+            --link-color: #8cf;
+            --highlight-color: #ff8000;
+            --border-color: #446979;
+            --top-color: #313536;
+            --bottom-color: #1D2021;
+            --h1-color: #888;
+            --h2-color: #777;
+            --h3-color: #666;
+            --h4-color: #d7ba7d;
+            --code-color: #d7ba7d;
+            --cite-color: #777;
+
+            /* Misc */
+            --margin: 10px;
+            --padding: 10px;
+            --radius: 8px;
+            --border: 1px solid var(--top-color);
+        }
+
+        * {
+            margin: 0px;
+            padding: 0px;
+        }
+
+        /* Layout */
+        body {
+            background-color: var(--bottom-color);
+            color: var(--font-color);
+            font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,sans-serif;
+        }
+
+        nav {
+            background-color: var(--bottom-color);
+            border-radius: var(--radius) var(--radius) 0px 0px;
+            font-size: 90%;
+        }
+
+        footer {
+            color: var(--font-color2);
+            background-color: var(--top-color);
+            border-left: var(--border);
+            border-right: var(--border);
+            border-bottom: var(--border);
+            border-radius: 0px 0px var(--radius) var(--radius);
+            font-size: 70%;
+            text-align: center;
+        }
+
+        footer a:link, footer a:visited {
+            color: var(--font-color2);
+            text-decoration: underline;
+        }
+
+        footer a:hover {
+            color: var(--link-color);
+            text-decoration: none;
+        }
+
+        #container {
+            width: 100%;
+        }
+
+        #split {
+            display: table;
+            padding-top: var(--padding);
+            border-left: var(--border);
+            border-right: var(--border);
+        }
+
+        #content {
+            display: table-cell;
+            padding-right: var(--padding);
+        }
+
+        #content h1 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+            margin-bottom: 10px;
+        }
+
+        #content h2 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+            margin-bottom: 10px;
+        }
+
+        #sidebar a {
+            display: block;
+        }
+
+        #header {
+            background-color: var(--top-color);
+            width: 100%;
+        }
+
+        #headline, #split, nav, footer {
+            width: 70%;
+            margin: 0px auto;
+            padding: var(--padding);
+
+            /* Stupid hack */
+            min-width: 844px;
+        }
+
+        @media screen and (max-width: 899px) {
+            #headline, #split, nav, footer {
+                width: 100%;
+            }
+        }
+
+        #headline h1 {
+            display: inline-block;
+            text-decoration: none;
+            border-bottom: none;
+        }
+
+        #headline h2 {
+            display: inline-block;
+            padding-left: var(--padding);
+            border-bottom: none;
+        }
+
+        /* Text */
+        a:link, a:visited {
+            text-decoration: none;
+            color: var(--link-color);
+        }
+
+        a:hover {
+            color: var(--highlight-color);
+        }
+
+        h1 {
+            color: var(--h1-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+        }
+
+        h2 {
+            color: var(--h2-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+        }
+
+        h3 {
+            color: var(--h3-color);
+            text-decoration: underline;
+            display: inline;
+        }
+
+        h3, h4 {
+            padding-top: 10px;
+        }
+
+        h4 {
+            color: var(--h4-color);
+        }
+
+        .post-content li {
+            margin-left: 40px;
+            padding: 0px 0px var(--padding) 0px;
+            color: var(--font-color2);
+        }
+    </style>
+</head>
+<body>
+<div id="container">
+    <div id="header">
+        <div id="headline">
+            <h1>unexist.dev</h1>
+            <h2></h2>
+            <h2></h2>
+            <p>Showcase for @project.artifactId@</p>
+        </div>
+        <nav>
+            <a href="/">Home</a>
+            <a href="https://unexist.dev">Projects</a>
+            <a href="https://hg.unexist.dev">Repositories</a>
+        </nav>
+    </div>
+    <div id="split">
+        <div id="content">
+            <div id="posts">
+                <h2>Information</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li>
+                            <h3>Group</h3>: @project.groupId@
+                        </li>
+                        <li>
+                            <h3>Artifact</h3>: @project.artifactId@
+                        </li>
+                        <li>
+                            <h3>Version</h3>: @project.version@
+                        </li>
+                        <li>
+                            <h3>Build</h3> on @timestamp@ by @hg.author@
+                        </li>
+                    </ul>
+                </div>
+
+                <h2>Links</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li><a href="/q/dev">Developer console</a></li>
+                        <li><a href="/q/swagger-ui">Swagger UI</a></li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+    <footer>
+        <a href="/feed.xml">RSS</a>
+        &middot;
+        <a href="https://github.com/unexist">unexist @ GitHub</a>
+        &middot;
+        <a href="https://twitter.com/chkappel">unexist @ Twitter</a>
+    </footer>
+</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,1 @@
+dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngineProvider
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/resources/application.properties	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,38 @@
+# Configuration file
+# key = value
+#quarkus.swagger-ui.always-include=true
+#quarkus.servlet.context-path=/todo
+
+# Disable pass-though of infrastructure health
+#quarkus.datasource.health=false
+#quarkus.reactive-messaging.enabled=false
+#kafka.health.enabled=false
+
+# Opencontainers labels (https://github.com/opencontainers/image-spec/blob/master/annotations.md)
+quarkus.jib.labels."org.opencontainers.image.created"=@timestamp@
+quarkus.jib.labels."org.opencontainers.image.authors"=@hg.author@
+quarkus.jib.labels."org.opencontainers.image.url"=https://unexist.dev
+#quarkus.jib.labels."org.opencontainers.image.documentation"=DOCS
+#quarkus.jib.labels."org.opencontainers.image.source"=SRC
+quarkus.jib.labels."org.opencontainers.image.version"=@project.version@
+quarkus.jib.labels."org.opencontainers.image.revision"=@hg.rev@
+quarkus.jib.labels."org.opencontainers.image.licenses"=GPLv3
+quarkus.jib.labels."org.opencontainers.image.title"=@project.artifactId@
+quarkus.jib.labels."org.opencontainers.image.description"=@project.name@
+
+# OpenAPI3 specifications (https://quarkus.io/blog/openapi-for-everyone)
+mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@
+%dev.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [development]
+%test.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [test]
+mp.openapi.extensions.smallrye.info.version=@project.version@
+mp.openapi.extensions.smallrye.info.description=Last build on @timestamp@
+mp.openapi.extensions.smallrye.info.contact.email=christoph@unexist.dev
+mp.openapi.extensions.smallrye.info.contact.name=@hg.author@
+mp.openapi.extensions.smallrye.info.contact.url=https://unexist.dev
+mp.openapi.extensions.smallrye.info.license.name=Apache License v2.0
+mp.openapi.extensions.smallrye.info.license.url=https://www.apache.org/licenses/LICENSE-2.0
+
+# Database
+quarkus.datasource.db-kind=h2
+quarkus.datasource.username=username-default
+#quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/main/resources/todo.bpmn	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
+                  id="Definitions_0aui0ws" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler"
+                  exporterVersion="4.8.1">
+  <bpmn:process id="todo" name="Todo" isExecutable="true" camunda:versionTag="0.1">
+    <bpmn:startEvent id="StartEvent_1" name="Todo Retrieved">
+      <bpmn:outgoing>SequenceFlow_1p2szow</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:serviceTask id="Task_19pt1nu" name="Tally Todo " camunda:class="dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask">
+      <bpmn:incoming>SequenceFlow_04u8b2b</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_1axd8hr</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:endEvent id="EndEvent_1oyw02k" name="Todo Done">
+      <bpmn:incoming>SequenceFlow_1axd8hr</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_1axd8hr" sourceRef="Task_19pt1nu" targetRef="EndEvent_1oyw02k" />
+    <bpmn:serviceTask id="Task_0q4zvgp" name="Check Todo" camunda:delegateExpression="${camundaTodoCheckTask}">
+      <bpmn:incoming>SequenceFlow_1p2szow</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_04u8b2b</bpmn:outgoing>
+    </bpmn:serviceTask>
+    <bpmn:sequenceFlow id="SequenceFlow_1p2szow" sourceRef="StartEvent_1" targetRef="Task_0q4zvgp" />
+    <bpmn:sequenceFlow id="SequenceFlow_04u8b2b" sourceRef="Task_0q4zvgp" targetRef="Task_19pt1nu" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="todo">
+      <bpmndi:BPMNEdge id="SequenceFlow_04u8b2b_di" bpmnElement="SequenceFlow_04u8b2b">
+        <di:waypoint x="410" y="119" />
+        <di:waypoint x="480" y="119" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1p2szow_di" bpmnElement="SequenceFlow_1p2szow">
+        <di:waypoint x="200" y="119" />
+        <di:waypoint x="310" y="119" />
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1axd8hr_di" bpmnElement="SequenceFlow_1axd8hr">
+        <di:waypoint x="580" y="119" />
+        <di:waypoint x="662" y="119" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="345.5" y="98.5" width="90" height="13" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="164" y="101" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="145" y="137" width="74" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_17yjgnl_di" bpmnElement="Task_19pt1nu">
+        <dc:Bounds x="480" y="79" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_1oyw02k_di" bpmnElement="EndEvent_1oyw02k">
+        <dc:Bounds x="662" y="101" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="654" y="147" width="54" height="14" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="ServiceTask_1m8bv3v_di" bpmnElement="Task_0q4zvgp">
+        <dc:Bounds x="310" y="79" width="100" height="80" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-camunda-rest-engine-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,29 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Stupid integration test
+ * @copyright 2020-2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+
+@QuarkusTest
+public class TodoResourceTest {
+
+    @Test
+    public void testTodoEndpoint() {
+        given()
+          .when().get("/todo")
+          .then()
+             .statusCode(204);
+    }
+}
\ No newline at end of file
--- a/todo-service-camunda/pom.xml	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-<?xml version="1.0"?>
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
-         xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>todo-service-camunda</artifactId>
-    <version>0.1</version>
-
-    <parent>
-        <groupId>dev.unexist.showcase</groupId>
-        <artifactId>showcase-workflow-quarkus</artifactId>
-        <version>0.1</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <properties>
-        <camunda-bom.version>7.15.0</camunda-bom.version>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.camunda.bpm</groupId>
-                <artifactId>camunda-bom</artifactId>
-                <version>${camunda-bom.version}</version>
-                <scope>import</scope>
-                <type>pom</type>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <dependencies>
-        <!-- Quarkus -->
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-container-image-jib</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-jdbc-h2</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-agroal</artifactId>
-        </dependency>
-
-        <!-- Camunda -->
-        <dependency>
-            <groupId>org.camunda.bpm</groupId>
-            <artifactId>camunda-engine</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.camunda.bpm</groupId>
-            <artifactId>camunda-engine-cdi</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.camunda.bpm</groupId>
-            <artifactId>camunda-engine-rest</artifactId>
-            <classifier>classes</classifier>
-        </dependency>
-
-        <!-- Camunda JSON/XML handling -->
-        <dependency>
-            <groupId>org.camunda.bpm</groupId>
-            <artifactId>camunda-engine-plugin-spin</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.camunda.spin</groupId>
-            <artifactId>camunda-spin-dataformat-json-jackson</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.datatype</groupId>
-            <artifactId>jackson-datatype-jsr353</artifactId>
-        </dependency>
-    </dependencies>
-</project>
--- a/todo-service-camunda/src/main/docker/Dockerfile.fast-jar	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
-#
-# Before building the container image run:
-#
-# mvn package
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/quarkus-kubernetes-showcase-fast-jar .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-fast-jar
-#
-# If you want to include the debug port into your docker image
-# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
-# 
-# Then run the container using : 
-#
-# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-fast-jar
-#
-###
-FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
-
-ARG JAVA_PACKAGE=java-11-openjdk-headless
-ARG RUN_JAVA_VERSION=1.3.8
-
-ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
-
-# Install java and the run-java script
-# Also set up permissions for user `1001`
-RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
-    && microdnf update \
-    && microdnf clean all \
-    && mkdir /deployments \
-    && chown 1001 /deployments \
-    && chmod "g+rwX" /deployments \
-    && chown 1001:root /deployments \
-    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
-    && chown 1001 /deployments/run-java.sh \
-    && chmod 540 /deployments/run-java.sh \
-    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
-
-# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
-ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
-
-# We make four distinct layers so if there are application changes the library layers can be re-used
-COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
-COPY --chown=1001 target/quarkus-app/*.jar /deployments/
-COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
-COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
-
-EXPOSE 8080
-USER 1001
-
-ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- a/todo-service-camunda/src/main/docker/Dockerfile.jvm	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
-#
-# Before building the container image run:
-#
-# mvn package
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-kubernetes-showcase-jvm .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-jvm
-#
-# If you want to include the debug port into your docker image
-# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
-# 
-# Then run the container using : 
-#
-# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-jvm
-#
-###
-FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
-
-ARG JAVA_PACKAGE=java-11-openjdk-headless
-ARG RUN_JAVA_VERSION=1.3.8
-
-ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
-
-# Install java and the run-java script
-# Also set up permissions for user `1001`
-RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
-    && microdnf update \
-    && microdnf clean all \
-    && mkdir /deployments \
-    && chown 1001 /deployments \
-    && chmod "g+rwX" /deployments \
-    && chown 1001:root /deployments \
-    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
-    && chown 1001 /deployments/run-java.sh \
-    && chmod 540 /deployments/run-java.sh \
-    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
-
-# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
-ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
-
-COPY target/lib/* /deployments/lib/
-COPY target/*-runner.jar /deployments/app.jar
-
-EXPOSE 8080
-USER 1001
-
-ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- a/todo-service-camunda/src/main/docker/Dockerfile.native	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
-#
-# Before building the container image run:
-#
-# mvn package -Pnative -Dquarkus.native.container-build=true
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-kubernetes-showcase .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase
-#
-###
-FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
-WORKDIR /work/
-RUN chown 1001 /work \
-    && chmod "g+rwX" /work \
-    && chown 1001:root /work
-COPY --chown=1001:root target/*-runner /work/application
-
-EXPOSE 8080
-USER 1001
-
-CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/CamundaResource.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Camunda resource
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.adapter;
-
-import dev.unexist.showcase.todo.domain.todo.TodoBase;
-import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
-import io.agroal.api.AgroalDataSource;
-import org.camunda.bpm.engine.ProcessEngine;
-import org.camunda.bpm.engine.runtime.ProcessInstance;
-import org.camunda.bpm.engine.variable.Variables;
-import org.camunda.bpm.engine.variable.value.ObjectValue;
-import org.eclipse.microprofile.openapi.annotations.Operation;
-import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
-import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
-import org.eclipse.microprofile.openapi.annotations.tags.Tag;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import java.net.URI;
-
-@Path("/camunda")
-public class CamundaResource {
-    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaResource.class);
-
-    @Inject
-    CamundaEngine camundaEngine;
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Create new todo")
-    @Tag(name = "Todo")
-    @APIResponses({
-            @APIResponse(responseCode = "201", description = "Todo created"),
-            @APIResponse(responseCode = "406", description = "Bad data"),
-            @APIResponse(responseCode = "500", description = "Server error")
-    })
-    public Response create(TodoBase base, @Context UriInfo info) {
-        ProcessEngine ProcEngine = this.camundaEngine.getProcessEngine();
-
-        ObjectValue todoAsJson = Variables.objectValue(base)
-                        .serializationDataFormat("application/json").create();
-
-        ProcessInstance processInstance = ProcEngine.getRuntimeService()
-                .createProcessInstanceByKey("todo")
-                .setVariable("todo", todoAsJson)
-                .executeWithVariablesInReturn();
-
-        String id = processInstance.getId();
-
-        URI uri = info.getAbsolutePathBuilder().path("/" + id).build();
-
-        LOGGER.info("Process {} started", id);
-
-        return Response.created(uri).build();
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo resource
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.adapter;
-
-import dev.unexist.showcase.todo.domain.todo.Todo;
-import dev.unexist.showcase.todo.domain.todo.TodoBase;
-import dev.unexist.showcase.todo.domain.todo.TodoService;
-import org.eclipse.microprofile.openapi.annotations.Operation;
-import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
-import org.eclipse.microprofile.openapi.annotations.media.Content;
-import org.eclipse.microprofile.openapi.annotations.media.Schema;
-import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
-import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
-import org.eclipse.microprofile.openapi.annotations.tags.Tag;
-
-import javax.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.List;
-import java.util.Optional;
-
-@Path("/todo")
-public class TodoResource {
-
-    @Inject
-    TodoService todoService;
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Create new todo")
-    @Tag(name = "Todo")
-    @APIResponses({
-            @APIResponse(responseCode = "201", description = "Todo created"),
-            @APIResponse(responseCode = "406", description = "Bad data"),
-            @APIResponse(responseCode = "500", description = "Server error")
-    })
-    public Response create(TodoBase base) {
-        Response.ResponseBuilder response;
-
-        if (this.todoService.create(base)) {
-            response = Response.status(Response.Status.CREATED);
-        } else {
-            response = Response.status(Response.Status.NOT_ACCEPTABLE);
-        }
-
-        return response.build();
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Get all todos")
-    @Tag(name = "Todo")
-    @APIResponses({
-            @APIResponse(responseCode = "200", description = "List of todo", content =
-                @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = Todo.class))),
-            @APIResponse(responseCode = "204", description = "Nothing found"),
-            @APIResponse(responseCode = "500", description = "Server error")
-    })
-    public Response getAll() {
-        List<Todo> todoList = this.todoService.getAll();
-
-        Response.ResponseBuilder response;
-
-        if (todoList.isEmpty()) {
-            response = Response.noContent();
-        } else {
-            response = Response.ok(Entity.json(todoList));
-        }
-
-        return response.build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Get todo by id")
-    @Tag(name = "Todo")
-    @APIResponses({
-            @APIResponse(responseCode = "200", description = "Todo found", content =
-                @Content(schema = @Schema(implementation = Todo.class))),
-            @APIResponse(responseCode = "404", description = "Todo not found"),
-            @APIResponse(responseCode = "500", description = "Server error")
-    })
-    public Response findById(@PathParam("id") int id) {
-        Optional<Todo> result = this.todoService.findById(id);
-
-        Response.ResponseBuilder response;
-
-        if (result.isPresent()) {
-            response = Response.ok(Entity.json(result.get()));
-        } else {
-            response = Response.status(Response.Status.NOT_FOUND);
-        }
-
-        return response.build();
-    }
-
-    @PUT
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Update todo by id")
-    @Tag(name = "Todo")
-    @APIResponses({
-            @APIResponse(responseCode = "204", description = "Todo updated"),
-            @APIResponse(responseCode = "404", description = "Todo not found"),
-            @APIResponse(responseCode = "500", description = "Server error")
-    })
-    public Response update(@PathParam("id") int id, TodoBase base) {
-        Response.ResponseBuilder response;
-
-        if (this.todoService.update(id, base)) {
-            response = Response.noContent();
-        } else {
-            response = Response.status(Response.Status.NOT_FOUND);
-        }
-
-        return response.build();
-    }
-
-    @DELETE
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    @Operation(summary = "Delete todo by id")
-    @Tag(name = "Todo")
-    public Response delete(@PathParam("id") int id) {
-        Response.ResponseBuilder response;
-
-        if (this.todoService.delete(id)) {
-            response = Response.noContent();
-        } else {
-            response = Response.status(Response.Status.NOT_FOUND);
-        }
-
-        return response.build();
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoCheckTask.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Camunda todo check task
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.adapter.tasks;
-
-import dev.unexist.showcase.todo.domain.todo.TodoBase;
-import dev.unexist.showcase.todo.domain.todo.TodoService;
-import org.camunda.bpm.engine.delegate.DelegateExecution;
-import org.camunda.bpm.engine.delegate.JavaDelegate;
-import org.camunda.bpm.engine.variable.VariableMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.enterprise.context.Dependent;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-@Dependent
-@Named
-public class CamundaTodoCheckTask implements JavaDelegate {
-    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoCheckTask.class);
-
-    @Inject
-    TodoService todoService;
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        VariableMap varMap = execution.getVariablesTyped();
-
-        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
-
-        LOGGER.info("Todo check task: {}, total: {}", todo, this.todoService);
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/adapter/tasks/CamundaTodoTallyTask.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Camunda todo tally task
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.adapter.tasks;
-
-import dev.unexist.showcase.todo.domain.todo.TodoBase;
-import org.camunda.bpm.engine.delegate.DelegateExecution;
-import org.camunda.bpm.engine.delegate.JavaDelegate;
-import org.camunda.bpm.engine.variable.VariableMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.enterprise.context.Dependent;
-import javax.inject.Named;
-
-@Dependent
-@Named
-public class CamundaTodoTallyTask implements JavaDelegate {
-    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaTodoTallyTask.class);
-
-    @Override
-    public void execute(DelegateExecution execution) throws Exception {
-        VariableMap varMap = execution.getVariablesTyped();
-
-        final TodoBase todo = varMap.getValue("todo", TodoBase.class);
-
-        LOGGER.info("Todo tally task: {}", todo);
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo application
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.application;
-
-import dev.unexist.showcase.todo.adapter.CamundaResource;
-import dev.unexist.showcase.todo.adapter.TodoResource;
-import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
-import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
-import dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngine;
-import org.camunda.bpm.engine.rest.impl.CamundaRestResources;
-
-import javax.ws.rs.core.Application;
-import java.util.HashSet;
-import java.util.Set;
-
-public class RestApplication extends Application {
-
-    @Override
-    public Set<Class<?>> getClasses() {
-        Set<Class<?>> classes = new HashSet<Class<?>>();
-
-        /* Add your own classes */
-        classes.add(TodoResource.class);
-        classes.add(CamundaResource.class);
-        classes.add(CamundaEngine.class);
-
-        /* Add tasks */
-        classes.add(CamundaTodoCheckTask.class);
-        classes.add(CamundaTodoTallyTask.class);
-
-        /* Add all camunda engine rest resources (or just add those that you actually need) */
-        classes.addAll(CamundaRestResources.getResourceClasses());
-
-        /* Mandatory */
-        classes.addAll(CamundaRestResources.getConfigurationClasses());
-
-        return classes;
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file DueDate class
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.domain.todo;
-
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import dev.unexist.showcase.todo.infrastructure.serializer.DateSerializer;
-
-import java.time.LocalDate;
-
-public class DueDate {
-    @JsonSerialize(using = DateSerializer.class)
-    private LocalDate start;
-
-    @JsonSerialize(using = DateSerializer.class)
-    private LocalDate due;
-
-    /**
-     * Get start date
-     *
-     * @return Start date
-     **/
-
-    public LocalDate getStart() {
-        return start;
-    }
-
-    /**
-     * Set start date
-     *
-     * @param start
-     *         Date to set
-     **/
-
-    public void setStart(LocalDate start) {
-        this.start = start;
-    }
-
-    /**
-     * Get due date
-     *
-     * @return Due date
-     **/
-
-    public LocalDate getDue() {
-        return due;
-    }
-
-    /**
-     * Set due date
-     *
-     * @param due
-     *         Date to set
-     **/
-
-    public void setDue(LocalDate due) {
-        this.due = due;
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo class and aggregate root
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.domain.todo;
-
-public class Todo extends TodoBase {
-    private int id;
-
-    /**
-     * Constructor
-     **/
-
-    public Todo() {
-    }
-
-    /**
-     * Constructor
-     *
-     * @param  base  Base entry
-     **/
-
-    public Todo(final TodoBase base) {
-        this.update(base);
-    }
-
-    /**
-     * Update values from base
-     *
-     * @param  base  Todo base class
-     **/
-
-    public void update(final TodoBase base) {
-        this.setDueDate(base.getDueDate());
-        this.setTitle(base.getTitle());
-        this.setDescription(base.getDescription());
-        this.setDone(base.getDone());
-    }
-
-    /**
-     * Get id of entry
-     *
-     * @return Id of the entry
-     **/
-
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * Set id of entry
-     *
-     * @param  id  Id of the entry
-     **/
-
-    public void setId(int id) {
-        this.id = id;
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo base class
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.domain.todo;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import java.util.Objects;
-
-public class TodoBase {
-
-    @NotBlank
-    private String title;
-
-    @NotBlank
-    private String description;
-
-    private Boolean done;
-
-    @NotNull
-    private DueDate dueDate;
-
-    /**
-     * Get title of the entry
-     *
-     * @return Title of the entry
-     **/
-
-    public String getTitle() {
-        return title;
-    }
-
-    /**
-     * Set title of the entry
-     *
-     * @param  title  Title of the entry
-     **/
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    /**
-     * Get description of entry
-     *
-     * @return Description of the entry
-     **/
-
-    public String getDescription() {
-        return description;
-    }
-
-    /**
-     * Set description of the entry
-     *
-     * @param description
-     *          Description of the entry
-     **/
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    /**
-     * Get done state of entry
-     *
-     * @return Done state of the entry
-     **/
-
-    public Boolean getDone() {
-        return done;
-    }
-
-    /**
-     * Set done state of entry
-     *
-     * @param  done  Done state of the entry
-     **/
-
-    public void setDone(Boolean done) {
-        this.done = done;
-    }
-
-    /**
-     * Get due state of the entry
-     *
-     * @return Due state of the entry
-     **/
-
-    public DueDate getDueDate() {
-        return dueDate;
-    }
-
-    /**
-     * Set due date of the entry
-     *
-     * @param  dueDate  Due date of the entry
-     **/
-
-    public void setDueDate(DueDate dueDate) {
-        Objects.requireNonNull(dueDate, "DueDate cannot be null");
-
-        this.dueDate = dueDate;
-
-        if (null != dueDate.getStart() && null != dueDate.getDue()) {
-            this.done = dueDate.getStart().isBefore(dueDate.getDue());
-        }
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo repository interface
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.domain.todo;
-
-import java.util.List;
-import java.util.Optional;
-
-public interface TodoRepository {
-
-    /**
-     * Add {@link Todo} entry to list
-     *
-     * @param  todo  {@link Todo} entry to add
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    boolean add(Todo todo);
-
-    /**
-     * Update {@link Todo} with given id
-     *
-     * @param  todo  A {@link Todo} to update
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    boolean update(Todo todo);
-
-    /**
-     * Delete {@link Todo} with given id
-     *
-     * @param  id  Id to delete
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    boolean deleteById(int id);
-
-    /**
-     * Get all {@link Todo} entries
-     *
-     * @return List of all stored {@link Todo}
-     **/
-
-    List<Todo> getAll();
-
-    /**
-     * Find {@link Todo} by given id
-     *
-     * @param  id  Id to find
-     *
-     * @return A {@link Optional} with the result of the lookup
-     **/
-
-    Optional<Todo> findById(int id);
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo service and domain service
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.domain.todo;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import java.util.List;
-import java.util.Optional;
-
-@ApplicationScoped
-public class TodoService {
-
-    @Inject
-    TodoRepository todoRepository;
-
-    /**
-     * Create new {@link Todo} entry and store it in repository
-     *
-     * @param  base  A {@link TodoBase} entry
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    public boolean create(TodoBase base) {
-        Todo todo = new Todo(base);
-
-        return this.todoRepository.add(todo);
-    }
-
-    /**
-     * Update {@link Todo} at with given id
-     *
-     * @param  id    Id to update
-     * @param  base  Values for the entry
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    public boolean update(int id, TodoBase base) {
-        Optional<Todo> todo = this.findById(id);
-        boolean ret = false;
-
-        if (todo.isPresent()) {
-            todo.get().update(base);
-
-            ret = this.todoRepository.update(todo.get());
-        }
-
-        return ret;
-    }
-
-    /**
-     * Delete {@link Todo} with given id
-     *
-     * @param  id  Id to delete
-     *
-     * @return Either {@code true} on success; otherwise {@code false}
-     **/
-
-    public boolean delete(int id) {
-        return this.todoRepository.deleteById(id);
-    }
-
-    /**
-     * Get all {@link Todo} entries
-     *
-     * @return List of all {@link Todo}; might be empty
-     **/
-
-    public List<Todo> getAll() {
-        return this.todoRepository.getAll();
-    }
-
-    /**
-     * Find {@link Todo} by given id
-     *
-     * @param  id  Id to look for
-     *
-     * @return A {@link Optional} of the entry
-     **/
-
-    public Optional<Todo> findById(int id) {
-        return this.todoRepository.findById(id);
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngine.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Camunda engine helper
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.infrastructure.camunda;
-
-import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoCheckTask;
-import dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask;
-import io.agroal.api.AgroalDataSource;
-import org.camunda.bpm.engine.ProcessEngine;
-import org.camunda.bpm.engine.ProcessEngineConfiguration;
-import org.camunda.bpm.engine.RepositoryService;
-import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
-import org.camunda.bpm.engine.impl.cfg.StandaloneProcessEngineConfiguration;
-import org.camunda.bpm.engine.repository.ProcessDefinition;
-import org.camunda.bpm.model.bpmn.Bpmn;
-import org.camunda.bpm.model.bpmn.BpmnModelInstance;
-import org.camunda.spin.plugin.impl.SpinProcessEnginePlugin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.ClassUtils;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.sql.DataSource;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
-@ApplicationScoped
-public class CamundaEngine {
-    private static final Logger LOGGER = LoggerFactory.getLogger(CamundaEngine.class);
-
-    private ProcessEngine processEngine;
-
-    @Inject
-    AgroalDataSource defaultDataSource;
-
-    /**
-     * Get process engine
-     *
-     * @return Either newly created {@link ProcessEngine} or from cache
-     **/
-
-    public ProcessEngine getProcessEngine() {
-        if (null == this.processEngine) {
-            this.createProcessEngineWithDataSource(this.defaultDataSource);
-            this.deployProcess();
-        }
-
-        return this.processEngine;
-    }
-
-    /**
-     * Create new engine with given {@link DataSource}
-     *
-     * @param  dataSource  A {@link DataSource}
-     **/
-
-    private void createProcessEngineWithDataSource(DataSource dataSource) {
-        try {
-            StandaloneProcessEngineConfiguration config =
-                    new StandaloneProcessEngineConfiguration();
-
-            List<ProcessEnginePlugin> pluginList = List.of(new SpinProcessEnginePlugin());
-
-            /* Provide list of beans */
-            Map<Object, Object> beanList = Map.of(
-                    ClassUtils.getShortNameAsProperty(CamundaTodoCheckTask.class),
-                        CamundaTodoCheckTask.class,
-                    ClassUtils.getShortNameAsProperty(CamundaTodoTallyTask.class),
-                        CamundaTodoTallyTask.class
-            );
-
-            config.setDataSource(dataSource);
-            config.setDatabaseSchemaUpdate(
-                    ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
-            config.setJobExecutorActivate(true);
-            config.setProcessEnginePlugins(pluginList);
-            config.setBeans(beanList);
-
-            this.processEngine = config.buildProcessEngine();
-        } catch (Exception e) {
-            LOGGER.error("getProcessEngine", e);
-        }
-    }
-
-    /**
-     * Deploy process on cached engine
-     **/
-
-    private void deployProcess() {
-        RepositoryService repositoryService =
-                this.processEngine.getRepositoryService();
-
-        try {
-            ProcessDefinition process = repositoryService.createProcessDefinitionQuery()
-                    .processDefinitionKey("todo")
-                    .latestVersion()
-                    .singleResult();
-
-            if (null == process) {
-                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-                InputStream inputStream = classLoader.getResourceAsStream("todo.bpmn");
-
-                BpmnModelInstance todoInstance = Bpmn.readModelFromStream(inputStream);
-                repositoryService.createDeployment()
-                        .addModelInstance("todo.bpmn", todoInstance)
-                        .deploy();
-
-                LOGGER.info("Process definition inputStream deployed");
-            } else {
-                LOGGER.info("Process definition is activated");
-            }
-        } catch (RuntimeException e) {
-            LOGGER.error("deployProcesses", e);
-        }
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/camunda/CamundaEngineProvider.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Camunda engine provider
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.infrastructure.camunda;
-
-import org.camunda.bpm.engine.ProcessEngine;
-import org.camunda.bpm.engine.rest.spi.ProcessEngineProvider;
-
-import javax.inject.Inject;
-import java.util.HashSet;
-import java.util.Set;
-
-public class CamundaEngineProvider implements ProcessEngineProvider {
-
-    @Inject
-    CamundaEngine camundaEngine;
-
-    /**
-     * Get default process engine via SPI
-     *
-     * @return Default {@link ProcessEngine}
-     **/
-
-    public ProcessEngine getDefaultProcessEngine() {
-        return this.camundaEngine.getProcessEngine();
-    }
-
-    /**
-     * Get process engine by name
-     *
-     * @param  name  Name of the engine
-     *
-     * @return Found {@link ProcessEngine}
-     **/
-
-    public ProcessEngine getProcessEngine(String name) {
-        return this.camundaEngine.getProcessEngine();
-    }
-
-    /**
-     * Get list of all engine names
-     *
-     * @return List of known engine names
-     **/
-
-    public Set<String> getProcessEngineNames() {
-        Set<String> names = new HashSet<>();
-
-        names.add(this.camundaEngine.getProcessEngine().getName());
-
-        return names;
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo repository
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.infrastructure.persistence;
-
-import dev.unexist.showcase.todo.domain.todo.Todo;
-import dev.unexist.showcase.todo.domain.todo.TodoRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.enterprise.context.ApplicationScoped;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-@ApplicationScoped
-public class ListTodoRepository implements TodoRepository {
-    private static final Logger LOGGER = LoggerFactory.getLogger(ListTodoRepository.class);
-
-    private final List<Todo> list;
-
-    /**
-     * Constructor
-     **/
-
-    ListTodoRepository() {
-        this.list = new ArrayList<>();
-    }
-
-    @Override
-    public boolean add(final Todo todo) {
-        todo.setId(this.list.size() + 1);
-
-        return this.list.add(todo);
-    }
-
-    @Override
-    public boolean update(final Todo todo) {
-        boolean ret = false;
-
-        try {
-            this.list.set(todo.getId(), todo);
-
-            ret = true;
-        } catch (IndexOutOfBoundsException e) {
-            LOGGER.warn("update: id={} not found", todo.getId());
-        }
-
-        return ret;
-    }
-
-    @Override
-    public boolean deleteById(int id) {
-        boolean ret = false;
-
-        try {
-            this.list.remove(id);
-
-            ret = true;
-        } catch (IndexOutOfBoundsException e) {
-            LOGGER.warn("deleteById: id={} not found", id);
-        }
-
-        return ret;
-    }
-
-    @Override
-    public List<Todo> getAll() {
-        return Collections.unmodifiableList(this.list);
-    }
-
-    @Override
-    public Optional<Todo> findById(int id) {
-        return this.list.stream()
-                .filter(t -> t.getId() == id)
-                .findFirst();
-    }
-}
--- a/todo-service-camunda/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Todo serializer
- * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.infrastructure.serializer;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-
-import java.io.IOException;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-
-public class DateSerializer extends JsonSerializer<LocalDate> {
-    public static final String PATTERN = "yyyy-MM-dd";
-
-    /**
-     * Serialize {@link LocalDate} to format
-     *
-     * @param  value        Value to convert
-     * @param  gen          A {@link JsonGenerator}
-     * @param  serializers  A {@link SerializerProvider}
-     * @throws IOException
-     **/
-
-    @Override
-    public void serialize(LocalDate value, JsonGenerator gen,
-                          SerializerProvider serializers) throws IOException {
-        gen.writeString(value.format(DateTimeFormatter.ofPattern(PATTERN)));
-    }
-}
--- a/todo-service-camunda/src/main/resources/META-INF/resources/index.html	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="utf-8">
-    <title>unexist.dev</title>
-    <style type="text/css">
-        :root {
-            /* Colors */
-            --font-color: #fff;
-            --font-color2: #aaa;
-            --link-color: #8cf;
-            --highlight-color: #ff8000;
-            --border-color: #446979;
-            --top-color: #313536;
-            --bottom-color: #1D2021;
-            --h1-color: #888;
-            --h2-color: #777;
-            --h3-color: #666;
-            --h4-color: #d7ba7d;
-            --code-color: #d7ba7d;
-            --cite-color: #777;
-
-            /* Misc */
-            --margin: 10px;
-            --padding: 10px;
-            --radius: 8px;
-            --border: 1px solid var(--top-color);
-        }
-
-        * {
-            margin: 0px;
-            padding: 0px;
-        }
-
-        /* Layout */
-        body {
-            background-color: var(--bottom-color);
-            color: var(--font-color);
-            font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,sans-serif;
-        }
-
-        nav {
-            background-color: var(--bottom-color);
-            border-radius: var(--radius) var(--radius) 0px 0px;
-            font-size: 90%;
-        }
-
-        footer {
-            color: var(--font-color2);
-            background-color: var(--top-color);
-            border-left: var(--border);
-            border-right: var(--border);
-            border-bottom: var(--border);
-            border-radius: 0px 0px var(--radius) var(--radius);
-            font-size: 70%;
-            text-align: center;
-        }
-
-        footer a:link, footer a:visited {
-            color: var(--font-color2);
-            text-decoration: underline;
-        }
-
-        footer a:hover {
-            color: var(--link-color);
-            text-decoration: none;
-        }
-
-        #container {
-            width: 100%;
-        }
-
-        #split {
-            display: table;
-            padding-top: var(--padding);
-            border-left: var(--border);
-            border-right: var(--border);
-        }
-
-        #content {
-            display: table-cell;
-            padding-right: var(--padding);
-        }
-
-        #content h1 {
-            text-decoration: none;
-            border-bottom: 1px solid var(--h1-color);
-            margin-bottom: 10px;
-        }
-
-        #content h2 {
-            text-decoration: none;
-            border-bottom: 1px solid var(--h2-color);
-            margin-bottom: 10px;
-        }
-
-        #sidebar a {
-            display: block;
-        }
-
-        #header {
-            background-color: var(--top-color);
-            width: 100%;
-        }
-
-        #headline, #split, nav, footer {
-            width: 70%;
-            margin: 0px auto;
-            padding: var(--padding);
-
-            /* Stupid hack */
-            min-width: 844px;
-        }
-
-        @media screen and (max-width: 899px) {
-            #headline, #split, nav, footer {
-                width: 100%;
-            }
-        }
-
-        #headline h1 {
-            display: inline-block;
-            text-decoration: none;
-            border-bottom: none;
-        }
-
-        #headline h2 {
-            display: inline-block;
-            padding-left: var(--padding);
-            border-bottom: none;
-        }
-
-        /* Text */
-        a:link, a:visited {
-            text-decoration: none;
-            color: var(--link-color);
-        }
-
-        a:hover {
-            color: var(--highlight-color);
-        }
-
-        h1 {
-            color: var(--h1-color);
-            text-decoration: none;
-            border-bottom: 1px solid var(--h1-color);
-        }
-
-        h2 {
-            color: var(--h2-color);
-            text-decoration: none;
-            border-bottom: 1px solid var(--h2-color);
-        }
-
-        h3 {
-            color: var(--h3-color);
-            text-decoration: underline;
-            display: inline;
-        }
-
-        h3, h4 {
-            padding-top: 10px;
-        }
-
-        h4 {
-            color: var(--h4-color);
-        }
-
-        .post-content li {
-            margin-left: 40px;
-            padding: 0px 0px var(--padding) 0px;
-            color: var(--font-color2);
-        }
-    </style>
-</head>
-<body>
-<div id="container">
-    <div id="header">
-        <div id="headline">
-            <h1>unexist.dev</h1>
-            <h2></h2>
-            <h2></h2>
-            <p>Showcase for @project.artifactId@</p>
-        </div>
-        <nav>
-            <a href="/">Home</a>
-            <a href="https://unexist.dev">Projects</a>
-            <a href="https://hg.unexist.dev">Repositories</a>
-        </nav>
-    </div>
-    <div id="split">
-        <div id="content">
-            <div id="posts">
-                <h2>Information</h2>
-
-                <div class="post-content">
-                    <ul>
-                        <li>
-                            <h3>Group</h3>: @project.groupId@
-                        </li>
-                        <li>
-                            <h3>Artifact</h3>: @project.artifactId@
-                        </li>
-                        <li>
-                            <h3>Version</h3>: @project.version@
-                        </li>
-                        <li>
-                            <h3>Build</h3> on @timestamp@ by @hg.author@
-                        </li>
-                    </ul>
-                </div>
-
-                <h2>Links</h2>
-
-                <div class="post-content">
-                    <ul>
-                        <li><a href="/q/dev">Developer console</a></li>
-                        <li><a href="/q/swagger-ui">Swagger UI</a></li>
-                    </ul>
-                </div>
-            </div>
-        </div>
-    </div>
-    <footer>
-        <a href="/feed.xml">RSS</a>
-        &middot;
-        <a href="https://github.com/unexist">unexist @ GitHub</a>
-        &middot;
-        <a href="https://twitter.com/chkappel">unexist @ Twitter</a>
-    </footer>
-</div>
-</body>
-</html>
\ No newline at end of file
--- a/todo-service-camunda/src/main/resources/META-INF/services/org.camunda.bpm.engine.rest.spi.ProcessEngineProvider	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-dev.unexist.showcase.todo.infrastructure.camunda.CamundaEngineProvider
\ No newline at end of file
--- a/todo-service-camunda/src/main/resources/application.properties	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-# Configuration file
-# key = value
-#quarkus.swagger-ui.always-include=true
-#quarkus.servlet.context-path=/todo
-
-# Disable pass-though of infrastructure health
-#quarkus.datasource.health=false
-#quarkus.reactive-messaging.enabled=false
-#kafka.health.enabled=false
-
-# Opencontainers labels (https://github.com/opencontainers/image-spec/blob/master/annotations.md)
-quarkus.jib.labels."org.opencontainers.image.created"=@timestamp@
-quarkus.jib.labels."org.opencontainers.image.authors"=@hg.author@
-quarkus.jib.labels."org.opencontainers.image.url"=https://unexist.dev
-#quarkus.jib.labels."org.opencontainers.image.documentation"=DOCS
-#quarkus.jib.labels."org.opencontainers.image.source"=SRC
-quarkus.jib.labels."org.opencontainers.image.version"=@project.version@
-quarkus.jib.labels."org.opencontainers.image.revision"=@hg.rev@
-quarkus.jib.labels."org.opencontainers.image.licenses"=GPLv3
-quarkus.jib.labels."org.opencontainers.image.title"=@project.artifactId@
-quarkus.jib.labels."org.opencontainers.image.description"=@project.name@
-
-# OpenAPI3 specifications (https://quarkus.io/blog/openapi-for-everyone)
-mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@
-%dev.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [development]
-%test.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [test]
-mp.openapi.extensions.smallrye.info.version=@project.version@
-mp.openapi.extensions.smallrye.info.description=Last build on @timestamp@
-mp.openapi.extensions.smallrye.info.contact.email=christoph@unexist.dev
-mp.openapi.extensions.smallrye.info.contact.name=@hg.author@
-mp.openapi.extensions.smallrye.info.contact.url=https://unexist.dev
-mp.openapi.extensions.smallrye.info.license.name=Apache License v2.0
-mp.openapi.extensions.smallrye.info.license.url=https://www.apache.org/licenses/LICENSE-2.0
-
-# Database
-quarkus.datasource.db-kind=h2
-quarkus.datasource.username=username-default
-#quarkus.datasource.jdbc.url=jdbc:h2:tcp://localhost/mem:default
\ No newline at end of file
--- a/todo-service-camunda/src/main/resources/todo.bpmn	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0aui0ws" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1">
-  <bpmn:process id="todo" name="Todo" isExecutable="true" camunda:versionTag="0.1">
-    <bpmn:startEvent id="StartEvent_1" name="Todo Retrieved">
-      <bpmn:outgoing>SequenceFlow_1p2szow</bpmn:outgoing>
-    </bpmn:startEvent>
-    <bpmn:serviceTask id="Task_19pt1nu" name="Tally Todo " camunda:class="dev.unexist.showcase.todo.adapter.tasks.CamundaTodoTallyTask">
-      <bpmn:incoming>SequenceFlow_04u8b2b</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_1axd8hr</bpmn:outgoing>
-    </bpmn:serviceTask>
-    <bpmn:endEvent id="EndEvent_1oyw02k" name="Todo Done">
-      <bpmn:incoming>SequenceFlow_1axd8hr</bpmn:incoming>
-    </bpmn:endEvent>
-    <bpmn:sequenceFlow id="SequenceFlow_1axd8hr" sourceRef="Task_19pt1nu" targetRef="EndEvent_1oyw02k" />
-    <bpmn:serviceTask id="Task_0q4zvgp" name="Check Todo" camunda:delegateExpression="${camundaTodoCheckTask}">
-      <bpmn:incoming>SequenceFlow_1p2szow</bpmn:incoming>
-      <bpmn:outgoing>SequenceFlow_04u8b2b</bpmn:outgoing>
-    </bpmn:serviceTask>
-    <bpmn:sequenceFlow id="SequenceFlow_1p2szow" sourceRef="StartEvent_1" targetRef="Task_0q4zvgp" />
-    <bpmn:sequenceFlow id="SequenceFlow_04u8b2b" sourceRef="Task_0q4zvgp" targetRef="Task_19pt1nu" />
-  </bpmn:process>
-  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
-    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="todo">
-      <bpmndi:BPMNEdge id="SequenceFlow_04u8b2b_di" bpmnElement="SequenceFlow_04u8b2b">
-        <di:waypoint x="410" y="119" />
-        <di:waypoint x="480" y="119" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1p2szow_di" bpmnElement="SequenceFlow_1p2szow">
-        <di:waypoint x="200" y="119" />
-        <di:waypoint x="310" y="119" />
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge id="SequenceFlow_1axd8hr_di" bpmnElement="SequenceFlow_1axd8hr">
-        <di:waypoint x="580" y="119" />
-        <di:waypoint x="662" y="119" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="345.5" y="98.5" width="90" height="13" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
-        <dc:Bounds x="164" y="101" width="36" height="36" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="145" y="137" width="74" height="14" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="ServiceTask_17yjgnl_di" bpmnElement="Task_19pt1nu">
-        <dc:Bounds x="480" y="79" width="100" height="80" />
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="EndEvent_1oyw02k_di" bpmnElement="EndEvent_1oyw02k">
-        <dc:Bounds x="662" y="101" width="36" height="36" />
-        <bpmndi:BPMNLabel>
-          <dc:Bounds x="654" y="147" width="54" height="14" />
-        </bpmndi:BPMNLabel>
-      </bpmndi:BPMNShape>
-      <bpmndi:BPMNShape id="ServiceTask_1m8bv3v_di" bpmnElement="Task_0q4zvgp">
-        <dc:Bounds x="310" y="79" width="100" height="80" />
-      </bpmndi:BPMNShape>
-    </bpmndi:BPMNPlane>
-  </bpmndi:BPMNDiagram>
-</bpmn:definitions>
--- a/todo-service-camunda/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java	Mon Aug 16 17:32:14 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/**
- * @package Quarkus-Workflow-Showcase
- *
- * @file Stupid integration test
- * @copyright 2020-2021 Christoph Kappel <christoph@unexist.dev>
- * @version $Id$
- *
- * This program can be distributed under the terms of the Apache License v2.0.
- * See the file LICENSE for details.
- **/
-
-package dev.unexist.showcase.todo.application;
-
-import io.quarkus.test.junit.QuarkusTest;
-import org.junit.jupiter.api.Test;
-
-import static io.restassured.RestAssured.given;
-
-@QuarkusTest
-public class TodoResourceTest {
-
-    @Test
-    public void testTodoEndpoint() {
-        given()
-          .when().get("/todo")
-          .then()
-             .statusCode(204);
-    }
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/pom.xml	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>todo-service-kogito-quarkus</artifactId>
+    <version>0.1</version>
+
+    <parent>
+        <groupId>dev.unexist.showcase</groupId>
+        <artifactId>showcase-workflow-quarkus</artifactId>
+        <version>0.1</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <dependencies>
+        <!-- Quarkus -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-container-image-jib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-kafka-client</artifactId>
+        </dependency>
+
+        <!-- Kogito -->
+        <dependency>
+            <groupId>org.kie.kogito</groupId>
+            <artifactId>kogito-quarkus</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kie.kogito</groupId>
+            <artifactId>kogito-addons-quarkus-cloudevents</artifactId>
+        </dependency>
+    </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/docker/Dockerfile.fast-jar	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,57 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.fast-jar -t quarkus/quarkus-kubernetes-showcase-fast-jar .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-fast-jar
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+# We make four distinct layers so if there are application changes the library layers can be re-used
+COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
+COPY --chown=1001 target/quarkus-app/*.jar /deployments/
+COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
+COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/docker/Dockerfile.jvm	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,54 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
+#
+# Before building the container image run:
+#
+# mvn package
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-kubernetes-showcase-jvm .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase-jvm
+#
+# If you want to include the debug port into your docker image
+# you will have to expose the debug port (default 5005) like this :  EXPOSE 8080 5050
+# 
+# Then run the container using : 
+#
+# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/quarkus-kubernetes-showcase-jvm
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+
+ARG JAVA_PACKAGE=java-11-openjdk-headless
+ARG RUN_JAVA_VERSION=1.3.8
+
+ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
+
+# Install java and the run-java script
+# Also set up permissions for user `1001`
+RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
+    && microdnf update \
+    && microdnf clean all \
+    && mkdir /deployments \
+    && chown 1001 /deployments \
+    && chmod "g+rwX" /deployments \
+    && chown 1001:root /deployments \
+    && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
+    && chown 1001 /deployments/run-java.sh \
+    && chmod 540 /deployments/run-java.sh \
+    && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
+
+# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
+ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+
+COPY target/lib/* /deployments/lib/
+COPY target/*-runner.jar /deployments/app.jar
+
+EXPOSE 8080
+USER 1001
+
+ENTRYPOINT [ "/deployments/run-java.sh" ]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/docker/Dockerfile.native	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,27 @@
+####
+# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
+#
+# Before building the container image run:
+#
+# mvn package -Pnative -Dquarkus.native.container-build=true
+#
+# Then, build the image with:
+#
+# docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-kubernetes-showcase .
+#
+# Then run the container using:
+#
+# docker run -i --rm -p 8080:8080 quarkus/quarkus-kubernetes-showcase
+#
+###
+FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
+WORKDIR /work/
+RUN chown 1001 /work \
+    && chmod "g+rwX" /work \
+    && chown 1001:root /work
+COPY --chown=1001:root target/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/adapter/TodoResource.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,157 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo resource
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.adapter;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
+import org.eclipse.microprofile.openapi.annotations.media.Content;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+import org.eclipse.microprofile.openapi.annotations.tags.Tag;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+
+@Path("/todo")
+public class TodoResource {
+
+    @Inject
+    TodoService todoService;
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Create new todo")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "201", description = "Todo created"),
+            @APIResponse(responseCode = "406", description = "Bad data"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response create(TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.create(base)) {
+            response = Response.status(Response.Status.CREATED);
+        } else {
+            response = Response.status(Response.Status.NOT_ACCEPTABLE);
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get all todos")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "List of todo", content =
+                @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = Todo.class))),
+            @APIResponse(responseCode = "204", description = "Nothing found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response getAll() {
+        List<Todo> todoList = this.todoService.getAll();
+
+        Response.ResponseBuilder response;
+
+        if (todoList.isEmpty()) {
+            response = Response.noContent();
+        } else {
+            response = Response.ok(Entity.json(todoList));
+        }
+
+        return response.build();
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Get todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "200", description = "Todo found", content =
+                @Content(schema = @Schema(implementation = Todo.class))),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response findById(@PathParam("id") int id) {
+        Optional<Todo> result = this.todoService.findById(id);
+
+        Response.ResponseBuilder response;
+
+        if (result.isPresent()) {
+            response = Response.ok(Entity.json(result.get()));
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Update todo by id")
+    @Tag(name = "Todo")
+    @APIResponses({
+            @APIResponse(responseCode = "204", description = "Todo updated"),
+            @APIResponse(responseCode = "404", description = "Todo not found"),
+            @APIResponse(responseCode = "500", description = "Server error")
+    })
+    public Response update(@PathParam("id") int id, TodoBase base) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.update(id, base)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+
+    @DELETE
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(summary = "Delete todo by id")
+    @Tag(name = "Todo")
+    public Response delete(@PathParam("id") int id) {
+        Response.ResponseBuilder response;
+
+        if (this.todoService.delete(id)) {
+            response = Response.noContent();
+        } else {
+            response = Response.status(Response.Status.NOT_FOUND);
+        }
+
+        return response.build();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/application/KogitoService.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,64 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo class and aggregate root
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+import dev.unexist.showcase.todo.domain.todo.TodoService;
+import org.drools.core.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.time.LocalDate;
+
+@ApplicationScoped
+public class KogitoService {
+    private static final Logger LOGGER = LoggerFactory.getLogger(KogitoService.class);
+
+    @Inject
+    TodoService todoService;
+
+    /**
+     * Check values of given {@link TodoBase}
+     *
+     * @param  todo  A {@link TodoBase}
+     *
+     * @return Result message
+     **/
+
+    public String checkTodo(TodoBase todo) {
+        String result = StringUtils.EMPTY;
+
+        if (todo.getDueDate().getDue().isBefore(LocalDate.now())) {
+            result = "Due date is before current date!";
+        } else {
+            result = "OK";
+        }
+
+        LOGGER.info("Checked todo: {}", result);
+
+        return result;
+    }
+
+    /**
+     * Store given {@link TodoBase}
+     *
+     * @param  todo  A {@link TodoBase}
+     *
+     * @return Result message
+     **/
+
+    public String saveTodo(TodoBase todo) {
+        return (this.todoService.create(todo) ? "Todo saved" : "Todo not saved");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/application/RestApplication.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,17 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo application
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import javax.ws.rs.core.Application;
+
+public class RestApplication extends Application {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/DueDate.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,65 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file DueDate class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import dev.unexist.showcase.todo.infrastructure.serializer.DateSerializer;
+
+import java.time.LocalDate;
+
+public class DueDate {
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate start;
+
+    @JsonSerialize(using = DateSerializer.class)
+    private LocalDate due;
+
+    /**
+     * Get start date
+     *
+     * @return Start date
+     **/
+
+    public LocalDate getStart() {
+        return start;
+    }
+
+    /**
+     * Set start date
+     *
+     * @param  start  Date to set
+     **/
+
+    public void setStart(LocalDate start) {
+        this.start = start;
+    }
+
+    /**
+     * Get due date
+     *
+     * @return Due date
+     **/
+
+    public LocalDate getDue() {
+        return due;
+    }
+
+    /**
+     * Set due date
+     *
+     * @param  due  Date to set
+     **/
+
+    public void setDue(LocalDate due) {
+        this.due = due;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/Todo.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo class and aggregate root
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+public class Todo extends TodoBase {
+    private int id;
+
+    /**
+     * Constructor
+     **/
+
+    public Todo() {
+    }
+
+    /**
+     * Constructor
+     *
+     * @param  base  Base entry
+     **/
+
+    public Todo(final TodoBase base) {
+        this.update(base);
+    }
+
+    /**
+     * Update values from base
+     *
+     * @param  base  Todo base class
+     **/
+
+    public void update(final TodoBase base) {
+        this.setDueDate(base.getDueDate());
+        this.setTitle(base.getTitle());
+        this.setDescription(base.getDescription());
+        this.setDone(base.getDone());
+    }
+
+    /**
+     * Get id of entry
+     *
+     * @return Id of the entry
+     **/
+
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Set id of entry
+     *
+     * @param  id  Id of the entry
+     **/
+
+    public void setId(int id) {
+        this.id = id;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoBase.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,117 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo base class
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Objects;
+
+public class TodoBase {
+
+    @NotBlank
+    private String title;
+
+    @NotBlank
+    private String description;
+
+    private Boolean done;
+
+    @NotNull
+    private DueDate dueDate;
+
+    /**
+     * Get title of the entry
+     *
+     * @return Title of the entry
+     **/
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Set title of the entry
+     *
+     * @param  title  Title of the entry
+     **/
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * Get description of entry
+     *
+     * @return Description of the entry
+     **/
+
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Set description of the entry
+     *
+     * @param description
+     *          Description of the entry
+     **/
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * Get done state of entry
+     *
+     * @return Done state of the entry
+     **/
+
+    public Boolean getDone() {
+        return done;
+    }
+
+    /**
+     * Set done state of entry
+     *
+     * @param  done  Done state of the entry
+     **/
+
+    public void setDone(Boolean done) {
+        this.done = done;
+    }
+
+    /**
+     * Get due state of the entry
+     *
+     * @return Due state of the entry
+     **/
+
+    public DueDate getDueDate() {
+        return dueDate;
+    }
+
+    /**
+     * Set due date of the entry
+     *
+     * @param  dueDate  Due date of the entry
+     **/
+
+    public void setDueDate(DueDate dueDate) {
+        Objects.requireNonNull(dueDate, "DueDate cannot be null");
+
+        this.dueDate = dueDate;
+
+        if (null != dueDate.getStart() && null != dueDate.getDue()) {
+            this.done = dueDate.getStart().isBefore(dueDate.getDue());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,66 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository interface
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface TodoRepository {
+
+    /**
+     * Add {@link Todo} entry to list
+     *
+     * @param  todo  {@link Todo} entry to add
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean add(Todo todo);
+
+    /**
+     * Update {@link Todo} with given id
+     *
+     * @param  todo  A {@link Todo} to update
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean update(Todo todo);
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    boolean deleteById(int id);
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all stored {@link Todo}
+     **/
+
+    List<Todo> getAll();
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to find
+     *
+     * @return A {@link Optional} with the result of the lookup
+     **/
+
+    Optional<Todo> findById(int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/domain/todo/TodoService.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,94 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo service and domain service
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.domain.todo;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class TodoService {
+
+    @Inject
+    TodoRepository todoRepository;
+
+    /**
+     * Create new {@link Todo} entry and store it in repository
+     *
+     * @param  base  A {@link TodoBase} entry
+     *
+     * @return
+     **/
+
+    public boolean create(TodoBase base) {
+        Todo todo = new Todo(base);
+
+        return this.todoRepository.add(todo);
+    }
+
+    /**
+     * Update {@link Todo} at with given id
+     *
+     * @param  id    Id to update
+     * @param  base  Values for the entry
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean update(int id, TodoBase base) {
+        Optional<Todo> todo = this.findById(id);
+        boolean ret = false;
+
+        if (todo.isPresent()) {
+            todo.get().update(base);
+
+            ret = this.todoRepository.update(todo.get());
+        }
+
+        return ret;
+    }
+
+    /**
+     * Delete {@link Todo} with given id
+     *
+     * @param  id  Id to delete
+     *
+     * @return Either {@code true} on success; otherwise {@code false}
+     **/
+
+    public boolean delete(int id) {
+        return this.todoRepository.deleteById(id);
+    }
+
+    /**
+     * Get all {@link Todo} entries
+     *
+     * @return List of all {@link Todo}; might be empty
+     **/
+
+    public List<Todo> getAll() {
+        return this.todoRepository.getAll();
+    }
+
+    /**
+     * Find {@link Todo} by given id
+     *
+     * @param  id  Id to look for
+     *
+     * @return A {@link Optional} of the entry
+     **/
+
+    public Optional<Todo> findById(int id) {
+        return this.todoRepository.findById(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/persistence/ListTodoRepository.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,87 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo repository
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.persistence;
+
+import dev.unexist.showcase.todo.domain.todo.Todo;
+import dev.unexist.showcase.todo.domain.todo.TodoRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+@ApplicationScoped
+public class ListTodoRepository implements TodoRepository {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ListTodoRepository.class);
+
+    private final List<Todo> list;
+
+    /**
+     * Constructor
+     **/
+
+    ListTodoRepository() {
+        this.list = new ArrayList<>();
+    }
+
+    @Override
+    public boolean add(final Todo todo) {
+        todo.setId(this.list.size() + 1);
+
+        return this.list.add(todo);
+    }
+
+    @Override
+    public boolean update(final Todo todo) {
+        boolean ret = false;
+
+        try {
+            this.list.set(todo.getId(), todo);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("update: id={} not found", todo.getId());
+        }
+
+        return ret;
+    }
+
+    @Override
+    public boolean deleteById(int id) {
+        boolean ret = false;
+
+        try {
+            this.list.remove(id);
+
+            ret = true;
+        } catch (IndexOutOfBoundsException e) {
+            LOGGER.warn("update: id={} not found", id);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<Todo> getAll() {
+        return Collections.unmodifiableList(this.list);
+    }
+
+    @Override
+    public Optional<Todo> findById(int id) {
+        return this.list.stream()
+                .filter(t -> t.getId() == id)
+                .findFirst();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/java/dev/unexist/showcase/todo/infrastructure/serializer/DateSerializer.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,39 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Todo serializer
+ * @copyright 2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.infrastructure.serializer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class DateSerializer extends JsonSerializer<LocalDate> {
+    public static final String PATTERN = "yyyy-MM-dd";
+
+    /**
+     * Serialize {@link LocalDate} to format
+     *
+     * @param  value        Value to convert
+     * @param  gen          A {@link JsonGenerator}
+     * @param  serializers  A {@link SerializerProvider}
+     * @throws IOException
+     **/
+
+    @Override
+    public void serialize(LocalDate value, JsonGenerator gen,
+                          SerializerProvider serializers) throws IOException {
+        gen.writeString(value.format(DateTimeFormatter.ofPattern(PATTERN)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/resources/META-INF/resources/index.html	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,233 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>unexist.dev</title>
+    <style type="text/css">
+        :root {
+            /* Colors */
+            --font-color: #fff;
+            --font-color2: #aaa;
+            --link-color: #8cf;
+            --highlight-color: #ff8000;
+            --border-color: #446979;
+            --top-color: #313536;
+            --bottom-color: #1D2021;
+            --h1-color: #888;
+            --h2-color: #777;
+            --h3-color: #666;
+            --h4-color: #d7ba7d;
+            --code-color: #d7ba7d;
+            --cite-color: #777;
+
+            /* Misc */
+            --margin: 10px;
+            --padding: 10px;
+            --radius: 8px;
+            --border: 1px solid var(--top-color);
+        }
+
+        * {
+            margin: 0px;
+            padding: 0px;
+        }
+
+        /* Layout */
+        body {
+            background-color: var(--bottom-color);
+            color: var(--font-color);
+            font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,sans-serif;
+        }
+
+        nav {
+            background-color: var(--bottom-color);
+            border-radius: var(--radius) var(--radius) 0px 0px;
+            font-size: 90%;
+        }
+
+        footer {
+            color: var(--font-color2);
+            background-color: var(--top-color);
+            border-left: var(--border);
+            border-right: var(--border);
+            border-bottom: var(--border);
+            border-radius: 0px 0px var(--radius) var(--radius);
+            font-size: 70%;
+            text-align: center;
+        }
+
+        footer a:link, footer a:visited {
+            color: var(--font-color2);
+            text-decoration: underline;
+        }
+
+        footer a:hover {
+            color: var(--link-color);
+            text-decoration: none;
+        }
+
+        #container {
+            width: 100%;
+        }
+
+        #split {
+            display: table;
+            padding-top: var(--padding);
+            border-left: var(--border);
+            border-right: var(--border);
+        }
+
+        #content {
+            display: table-cell;
+            padding-right: var(--padding);
+        }
+
+        #content h1 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+            margin-bottom: 10px;
+        }
+
+        #content h2 {
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+            margin-bottom: 10px;
+        }
+
+        #sidebar a {
+            display: block;
+        }
+
+        #header {
+            background-color: var(--top-color);
+            width: 100%;
+        }
+
+        #headline, #split, nav, footer {
+            width: 70%;
+            margin: 0px auto;
+            padding: var(--padding);
+
+            /* Stupid hack */
+            min-width: 844px;
+        }
+
+        @media screen and (max-width: 899px) {
+            #headline, #split, nav, footer {
+                width: 100%;
+            }
+        }
+
+        #headline h1 {
+            display: inline-block;
+            text-decoration: none;
+            border-bottom: none;
+        }
+
+        #headline h2 {
+            display: inline-block;
+            padding-left: var(--padding);
+            border-bottom: none;
+        }
+
+        /* Text */
+        a:link, a:visited {
+            text-decoration: none;
+            color: var(--link-color);
+        }
+
+        a:hover {
+            color: var(--highlight-color);
+        }
+
+        h1 {
+            color: var(--h1-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h1-color);
+        }
+
+        h2 {
+            color: var(--h2-color);
+            text-decoration: none;
+            border-bottom: 1px solid var(--h2-color);
+        }
+
+        h3 {
+            color: var(--h3-color);
+            text-decoration: underline;
+            display: inline;
+        }
+
+        h3, h4 {
+            padding-top: 10px;
+        }
+
+        h4 {
+            color: var(--h4-color);
+        }
+
+        .post-content li {
+            margin-left: 40px;
+            padding: 0px 0px var(--padding) 0px;
+            color: var(--font-color2);
+        }
+    </style>
+</head>
+<body>
+<div id="container">
+    <div id="header">
+        <div id="headline">
+            <h1>unexist.dev</h1>
+            <h2></h2>
+            <h2></h2>
+            <p>Showcase for @project.artifactId@</p>
+        </div>
+        <nav>
+            <a href="/">Home</a>
+            <a href="https://unexist.dev">Projects</a>
+            <a href="https://hg.unexist.dev">Repositories</a>
+        </nav>
+    </div>
+    <div id="split">
+        <div id="content">
+            <div id="posts">
+                <h2>Information</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li>
+                            <h3>Group</h3>: @project.groupId@
+                        </li>
+                        <li>
+                            <h3>Artifact</h3>: @project.artifactId@
+                        </li>
+                        <li>
+                            <h3>Version</h3>: @project.version@
+                        </li>
+                        <li>
+                            <h3>Build</h3> on @timestamp@ by @hg.author@
+                        </li>
+                    </ul>
+                </div>
+
+                <h2>Links</h2>
+
+                <div class="post-content">
+                    <ul>
+                        <li><a href="/q/dev">Developer console</a></li>
+                        <li><a href="/q/swagger-ui">Swagger UI</a></li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+    <footer>
+        <a href="/feed.xml">RSS</a>
+        &middot;
+        <a href="https://github.com/unexist">unexist @ GitHub</a>
+        &middot;
+        <a href="https://twitter.com/chkappel">unexist @ Twitter</a>
+    </footer>
+</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/resources/application.properties	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,49 @@
+# Configuration file
+# key = value
+#quarkus.swagger-ui.always-include=true
+#quarkus.servlet.context-path=/todo
+
+# Disable pass-though of infrastructure health
+#quarkus.datasource.health=false
+#quarkus.reactive-messaging.enabled=false
+#kafka.health.enabled=false
+
+# Opencontainers labels (https://github.com/opencontainers/image-spec/blob/master/annotations.md)
+quarkus.jib.labels."org.opencontainers.image.created"=@timestamp@
+quarkus.jib.labels."org.opencontainers.image.authors"=@hg.author@
+quarkus.jib.labels."org.opencontainers.image.url"=https://unexist.dev
+#quarkus.jib.labels."org.opencontainers.image.documentation"=DOCS
+#quarkus.jib.labels."org.opencontainers.image.source"=SRC
+quarkus.jib.labels."org.opencontainers.image.version"=@project.version@
+quarkus.jib.labels."org.opencontainers.image.revision"=@hg.rev@
+quarkus.jib.labels."org.opencontainers.image.licenses"=GPLv3
+quarkus.jib.labels."org.opencontainers.image.title"=@project.artifactId@
+quarkus.jib.labels."org.opencontainers.image.description"=@project.name@
+
+# OpenAPI3 specifications (https://quarkus.io/blog/openapi-for-everyone)
+mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@
+%dev.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [development]
+%test.mp.openapi.extensions.smallrye.info.title=OpenAPI for @project.artifactId@ [test]
+mp.openapi.extensions.smallrye.info.version=@project.version@
+mp.openapi.extensions.smallrye.info.description=Last build on @timestamp@
+mp.openapi.extensions.smallrye.info.contact.email=christoph@unexist.dev
+mp.openapi.extensions.smallrye.info.contact.name=@hg.author@
+mp.openapi.extensions.smallrye.info.contact.url=https://unexist.dev
+mp.openapi.extensions.smallrye.info.license.name=Apache License v2.0
+mp.openapi.extensions.smallrye.info.license.url=https://www.apache.org/licenses/LICENSE-2.0
+
+# Messaging
+mp.messaging.incoming.kogito_incoming_stream.connector=smallrye-kafka
+mp.messaging.incoming.kogito_incoming_stream.topic=todo_in
+mp.messaging.incoming.kogito_incoming_stream.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+#mp.messaging.incoming.kogito_incoming_stream.bootstrap.servers=localhost:9092
+#mp.messaging.incoming.kogito_incoming_stream.auto.offset.reset=earliest
+
+
+mp.messaging.outgoing.kogito_outgoing_stream.connector=smallrye-kafka
+mp.messaging.outgoing.kogito_outgoing_stream.topic=todo_out
+mp.messaging.outgoing.kogito_outgoing_stream.serializer=org.apache.kafka.common.serialization.StringSerializer
+#mp.messaging.outgoing.kogito_outgoing_stream.bootstrap.servers=localhost:9092
+
+# uncomment below line if you don't want to use cloud event payload format
+#kogito.messaging.as-cloudevents=false
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/resources/dev/unexist/showcase/todo/todo.bpmn	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,597 @@
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpsim="http://www.bpsim.org/schemas/1.0" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:drools="http://www.jboss.org/drools" id="_ey7wMM32EDmwu7XcyDGIPQ" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd http://www.jboss.org/drools drools.xsd http://www.bpsim.org/schemas/1.0 bpsim.xsd http://www.omg.org/spec/DD/20100524/DC DC.xsd http://www.omg.org/spec/DD/20100524/DI DI.xsd " exporter="jBPM Process Modeler" exporterVersion="2.0" targetNamespace="http://www.omg.org/bpmn20">
+    <bpmn2:itemDefinition id="_todoItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="_resultItem" structureRef="String"/>
+    <bpmn2:itemDefinition id="__861122DB-2755-408E-A8CC-69F8CCC04E0F_namespaceInputXItem" structureRef="java.lang.String"/>
+    <bpmn2:itemDefinition id="__861122DB-2755-408E-A8CC-69F8CCC04E0F_modelInputXItem" structureRef="java.lang.String"/>
+    <bpmn2:itemDefinition id="__861122DB-2755-408E-A8CC-69F8CCC04E0F_decisionInputXItem" structureRef="java.lang.String"/>
+    <bpmn2:itemDefinition id="__861122DB-2755-408E-A8CC-69F8CCC04E0F_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__387FB4E7-AE40-4069-B415-195615766F78_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__387FB4E7-AE40-4069-B415-195615766F78_resultOutputXItem" structureRef="String"/>
+    <bpmn2:itemDefinition id="__4409773D-EF92-4DD3-8F6C-F952C27E8B1A_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__4409773D-EF92-4DD3-8F6C-F952C27E8B1A_resultOutputXItem" structureRef="String"/>
+    <bpmn2:itemDefinition id="__AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_todoOutputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="todo_inType" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__AEF1C263-7073-433A-8F35-A7C49A729B84_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__AEF1C263-7073-433A-8F35-A7C49A729B84_resultOutputXItem" structureRef="String"/>
+    <bpmn2:itemDefinition id="__38AF6677-7128-43AB-9552-3E1C822036FF_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="__38AF6677-7128-43AB-9552-3E1C822036FF_resultOutputXItem" structureRef="String"/>
+    <bpmn2:itemDefinition id="__386D55D9-CDD0-4EB3-93BC-99FBB3E538E1_todoInputXItem" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:itemDefinition id="todo_outType" structureRef="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+    <bpmn2:interface id="_387FB4E7-AE40-4069-B415-195615766F78_ServiceInterface" name="dev.unexist.showcase.todo.application.KogitoService" implementationRef="dev.unexist.showcase.todo.application.KogitoService">
+        <bpmn2:operation id="_387FB4E7-AE40-4069-B415-195615766F78_ServiceOperation" name="checkTodo" implementationRef="checkTodo"/>
+    </bpmn2:interface>
+    <bpmn2:interface id="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_ServiceInterface" name="dev.unexist.showcase.todo.application.KogitoService" implementationRef="dev.unexist.showcase.todo.application.KogitoService">
+        <bpmn2:operation id="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_ServiceOperation" name="saveTodo" implementationRef="saveTodo"/>
+    </bpmn2:interface>
+    <bpmn2:message id="_ezAosM32EDmwu7XcyDGIPQ" itemRef="todo_inType" name="todo_in"/>
+    <bpmn2:interface id="_AEF1C263-7073-433A-8F35-A7C49A729B84_ServiceInterface" name="dev.unexist.showcase.todo.application.KogitoService" implementationRef="dev.unexist.showcase.todo.application.KogitoService">
+        <bpmn2:operation id="_AEF1C263-7073-433A-8F35-A7C49A729B84_ServiceOperation" name="checkTodo" implementationRef="checkTodo"/>
+    </bpmn2:interface>
+    <bpmn2:interface id="_38AF6677-7128-43AB-9552-3E1C822036FF_ServiceInterface" name="dev.unexist.showcase.todo.application.KogitoService" implementationRef="dev.unexist.showcase.todo.application.KogitoService">
+        <bpmn2:operation id="_38AF6677-7128-43AB-9552-3E1C822036FF_ServiceOperation" name="saveTodo" implementationRef="saveTodo"/>
+    </bpmn2:interface>
+    <bpmn2:message id="_ezBPwM32EDmwu7XcyDGIPQ" itemRef="todo_outType" name="todo_out"/>
+    <bpmn2:process id="kogito" drools:packageName="dev.unexist.showcase.todo" drools:version="1.0" drools:adHoc="false" name="kogito" isExecutable="true" processType="Public">
+        <bpmn2:extensionElements>
+            <drools:import name="dev.unexist.showcase.todo.domain.todo.TodoBase"/>
+        </bpmn2:extensionElements>
+        <bpmn2:property id="todo" itemSubjectRef="_todoItem" name="todo"/>
+        <bpmn2:property id="result" itemSubjectRef="_resultItem" name="result"/>
+        <bpmn2:sequenceFlow id="_8939AE84-7DC6-4DD1-8EAD-6A60C6628EE4" sourceRef="_6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA" targetRef="_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1"/>
+        <bpmn2:sequenceFlow id="_92A3E94E-3162-425D-AE15-1EA8C3D46535" sourceRef="_38AF6677-7128-43AB-9552-3E1C822036FF" targetRef="_6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA"/>
+        <bpmn2:sequenceFlow id="_D7B776B2-1308-4C32-B610-17C625D90C4A" sourceRef="_E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769" targetRef="_38AF6677-7128-43AB-9552-3E1C822036FF"/>
+        <bpmn2:sequenceFlow id="_F08E870E-5755-4106-A1ED-6783E33A2B2F" sourceRef="_AEF1C263-7073-433A-8F35-A7C49A729B84" targetRef="_E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769"/>
+        <bpmn2:sequenceFlow id="_D20E2D87-6924-4D8B-9478-70C343074C18" sourceRef="_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6" targetRef="_AEF1C263-7073-433A-8F35-A7C49A729B84"/>
+        <bpmn2:sequenceFlow id="_2E37D9BC-CBC6-43FB-BB77-8A04589AC652" sourceRef="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A" targetRef="_AE3769CC-FF77-4A34-A0DA-88DFD1767C4B"/>
+        <bpmn2:sequenceFlow id="_EE2620C9-5B32-4C75-B0B7-689FA93CB842" sourceRef="_AE3769CC-FF77-4A34-A0DA-88DFD1767C4B" targetRef="_D4613D07-712A-4548-B031-AE7D6EF5D21F"/>
+        <bpmn2:sequenceFlow id="_D58996F7-7E62-469E-AA1B-98EAB4B1F79F" sourceRef="_656D38BC-B196-4069-B056-558680635036" targetRef="_04769C15-8ED3-40CE-9C0F-D19A387474F2"/>
+        <bpmn2:sequenceFlow id="_5DD76EFC-AB2A-4D5A-80BB-BBD0F40847AA" sourceRef="_861122DB-2755-408E-A8CC-69F8CCC04E0F" targetRef="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A"/>
+        <bpmn2:sequenceFlow id="_C0F5678E-4C29-4353-A7EB-5E09BB193172" name="is fine" sourceRef="_69803135-7AE7-4578-B094-EF4D1304143C" targetRef="_861122DB-2755-408E-A8CC-69F8CCC04E0F">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[is fine]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression" language="http://www.java.com/java"><![CDATA[return result.equals("OK");]]></bpmn2:conditionExpression>
+        </bpmn2:sequenceFlow>
+        <bpmn2:sequenceFlow id="_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2" name="is not" sourceRef="_69803135-7AE7-4578-B094-EF4D1304143C" targetRef="_656D38BC-B196-4069-B056-558680635036">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[is not]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+        </bpmn2:sequenceFlow>
+        <bpmn2:sequenceFlow id="_2B2A9AE1-7A13-4CE5-BF9C-02E65D834923" sourceRef="_387FB4E7-AE40-4069-B415-195615766F78" targetRef="_69803135-7AE7-4578-B094-EF4D1304143C"/>
+        <bpmn2:sequenceFlow id="SequenceFlow_1p2szow" sourceRef="StartEvent_1" targetRef="_387FB4E7-AE40-4069-B415-195615766F78"/>
+        <bpmn2:scriptTask id="_E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769" name="Output result" scriptFormat="http://www.java.com/java">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Output result]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_F08E870E-5755-4106-A1ED-6783E33A2B2F</bpmn2:incoming>
+            <bpmn2:outgoing>_D7B776B2-1308-4C32-B610-17C625D90C4A</bpmn2:outgoing>
+            <bpmn2:script>System.out.println("Result is = " + result);</bpmn2:script>
+        </bpmn2:scriptTask>
+        <bpmn2:endEvent id="_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1" name="Todo Sent">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Todo Sent]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_8939AE84-7DC6-4DD1-8EAD-6A60C6628EE4</bpmn2:incoming>
+            <bpmn2:dataInput id="_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__386D55D9-CDD0-4EB3-93BC-99FBB3E538E1_todoInputXItem" name="todo"/>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+            <bpmn2:inputSet>
+                <bpmn2:dataInputRefs>_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1_todoInputX</bpmn2:dataInputRefs>
+            </bpmn2:inputSet>
+            <bpmn2:messageEventDefinition drools:msgref="todo_out" messageRef="_ezBPwM32EDmwu7XcyDGIPQ"/>
+        </bpmn2:endEvent>
+        <bpmn2:scriptTask id="_6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA" name="Output result" scriptFormat="http://www.java.com/java">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Output result]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_92A3E94E-3162-425D-AE15-1EA8C3D46535</bpmn2:incoming>
+            <bpmn2:outgoing>_8939AE84-7DC6-4DD1-8EAD-6A60C6628EE4</bpmn2:outgoing>
+            <bpmn2:script>System.out.println("Result is = " + result);</bpmn2:script>
+        </bpmn2:scriptTask>
+        <bpmn2:serviceTask id="_38AF6677-7128-43AB-9552-3E1C822036FF" drools:serviceimplementation="Java" drools:serviceinterface="dev.unexist.showcase.todo.application.KogitoService" drools:serviceoperation="saveTodo" name="Store Todo" implementation="Java" operationRef="_38AF6677-7128-43AB-9552-3E1C822036FF_ServiceOperation">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Store Todo]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_D7B776B2-1308-4C32-B610-17C625D90C4A</bpmn2:incoming>
+            <bpmn2:outgoing>_92A3E94E-3162-425D-AE15-1EA8C3D46535</bpmn2:outgoing>
+            <bpmn2:ioSpecification>
+                <bpmn2:dataInput id="_38AF6677-7128-43AB-9552-3E1C822036FF_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__38AF6677-7128-43AB-9552-3E1C822036FF_todoInputXItem" name="todo"/>
+                <bpmn2:dataOutput id="_38AF6677-7128-43AB-9552-3E1C822036FF_resultOutputX" drools:dtype="String" itemSubjectRef="__38AF6677-7128-43AB-9552-3E1C822036FF_resultOutputXItem" name="result"/>
+                <bpmn2:inputSet>
+                    <bpmn2:dataInputRefs>_38AF6677-7128-43AB-9552-3E1C822036FF_todoInputX</bpmn2:dataInputRefs>
+                </bpmn2:inputSet>
+                <bpmn2:outputSet>
+                    <bpmn2:dataOutputRefs>_38AF6677-7128-43AB-9552-3E1C822036FF_resultOutputX</bpmn2:dataOutputRefs>
+                </bpmn2:outputSet>
+            </bpmn2:ioSpecification>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_38AF6677-7128-43AB-9552-3E1C822036FF_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+            <bpmn2:dataOutputAssociation>
+                <bpmn2:sourceRef>_38AF6677-7128-43AB-9552-3E1C822036FF_resultOutputX</bpmn2:sourceRef>
+                <bpmn2:targetRef>result</bpmn2:targetRef>
+            </bpmn2:dataOutputAssociation>
+        </bpmn2:serviceTask>
+        <bpmn2:serviceTask id="_AEF1C263-7073-433A-8F35-A7C49A729B84" drools:serviceimplementation="Java" drools:serviceinterface="dev.unexist.showcase.todo.application.KogitoService" drools:serviceoperation="checkTodo" name="Check Todo" implementation="Java" operationRef="_AEF1C263-7073-433A-8F35-A7C49A729B84_ServiceOperation">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Check Todo]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_D20E2D87-6924-4D8B-9478-70C343074C18</bpmn2:incoming>
+            <bpmn2:outgoing>_F08E870E-5755-4106-A1ED-6783E33A2B2F</bpmn2:outgoing>
+            <bpmn2:ioSpecification>
+                <bpmn2:dataInput id="_AEF1C263-7073-433A-8F35-A7C49A729B84_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__AEF1C263-7073-433A-8F35-A7C49A729B84_todoInputXItem" name="todo"/>
+                <bpmn2:dataOutput id="_AEF1C263-7073-433A-8F35-A7C49A729B84_resultOutputX" drools:dtype="String" itemSubjectRef="__AEF1C263-7073-433A-8F35-A7C49A729B84_resultOutputXItem" name="result"/>
+                <bpmn2:inputSet>
+                    <bpmn2:dataInputRefs>_AEF1C263-7073-433A-8F35-A7C49A729B84_todoInputX</bpmn2:dataInputRefs>
+                </bpmn2:inputSet>
+                <bpmn2:outputSet>
+                    <bpmn2:dataOutputRefs>_AEF1C263-7073-433A-8F35-A7C49A729B84_resultOutputX</bpmn2:dataOutputRefs>
+                </bpmn2:outputSet>
+            </bpmn2:ioSpecification>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_AEF1C263-7073-433A-8F35-A7C49A729B84_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+            <bpmn2:dataOutputAssociation>
+                <bpmn2:sourceRef>_AEF1C263-7073-433A-8F35-A7C49A729B84_resultOutputX</bpmn2:sourceRef>
+                <bpmn2:targetRef>result</bpmn2:targetRef>
+            </bpmn2:dataOutputAssociation>
+        </bpmn2:serviceTask>
+        <bpmn2:startEvent id="_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6" name="Todo Retrieved">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Todo Retrieved]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:outgoing>_D20E2D87-6924-4D8B-9478-70C343074C18</bpmn2:outgoing>
+            <bpmn2:dataOutput id="_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_todoOutputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_todoOutputXItem" name="todo"/>
+            <bpmn2:dataOutputAssociation>
+                <bpmn2:sourceRef>_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_todoOutputX</bpmn2:sourceRef>
+                <bpmn2:targetRef>todo</bpmn2:targetRef>
+            </bpmn2:dataOutputAssociation>
+            <bpmn2:outputSet>
+                <bpmn2:dataOutputRefs>_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_todoOutputX</bpmn2:dataOutputRefs>
+            </bpmn2:outputSet>
+            <bpmn2:messageEventDefinition drools:msgref="todo_in" messageRef="_ezAosM32EDmwu7XcyDGIPQ"/>
+        </bpmn2:startEvent>
+        <bpmn2:scriptTask id="_AE3769CC-FF77-4A34-A0DA-88DFD1767C4B" name="Output result" scriptFormat="http://www.java.com/java">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Output result]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_2E37D9BC-CBC6-43FB-BB77-8A04589AC652</bpmn2:incoming>
+            <bpmn2:outgoing>_EE2620C9-5B32-4C75-B0B7-689FA93CB842</bpmn2:outgoing>
+            <bpmn2:script>System.out.println("Result is = " + result);</bpmn2:script>
+        </bpmn2:scriptTask>
+        <bpmn2:serviceTask id="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A" drools:serviceimplementation="Java" drools:serviceinterface="dev.unexist.showcase.todo.application.KogitoService" drools:serviceoperation="saveTodo" name="Store Todo" implementation="Java" operationRef="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_ServiceOperation">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Store Todo]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_5DD76EFC-AB2A-4D5A-80BB-BBD0F40847AA</bpmn2:incoming>
+            <bpmn2:outgoing>_2E37D9BC-CBC6-43FB-BB77-8A04589AC652</bpmn2:outgoing>
+            <bpmn2:ioSpecification>
+                <bpmn2:dataInput id="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__4409773D-EF92-4DD3-8F6C-F952C27E8B1A_todoInputXItem" name="todo"/>
+                <bpmn2:dataOutput id="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_resultOutputX" drools:dtype="String" itemSubjectRef="__4409773D-EF92-4DD3-8F6C-F952C27E8B1A_resultOutputXItem" name="result"/>
+                <bpmn2:inputSet>
+                    <bpmn2:dataInputRefs>_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_todoInputX</bpmn2:dataInputRefs>
+                </bpmn2:inputSet>
+                <bpmn2:outputSet>
+                    <bpmn2:dataOutputRefs>_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_resultOutputX</bpmn2:dataOutputRefs>
+                </bpmn2:outputSet>
+            </bpmn2:ioSpecification>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+            <bpmn2:dataOutputAssociation>
+                <bpmn2:sourceRef>_4409773D-EF92-4DD3-8F6C-F952C27E8B1A_resultOutputX</bpmn2:sourceRef>
+                <bpmn2:targetRef>result</bpmn2:targetRef>
+            </bpmn2:dataOutputAssociation>
+        </bpmn2:serviceTask>
+        <bpmn2:endEvent id="_D4613D07-712A-4548-B031-AE7D6EF5D21F" name="Todo End">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Todo End]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_EE2620C9-5B32-4C75-B0B7-689FA93CB842</bpmn2:incoming>
+        </bpmn2:endEvent>
+        <bpmn2:endEvent id="_04769C15-8ED3-40CE-9C0F-D19A387474F2" name="error">
+            <bpmn2:documentation><![CDATA[Todo Error]]></bpmn2:documentation>
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[error]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_D58996F7-7E62-469E-AA1B-98EAB4B1F79F</bpmn2:incoming>
+        </bpmn2:endEvent>
+        <bpmn2:scriptTask id="_656D38BC-B196-4069-B056-558680635036" name="Output result" scriptFormat="http://www.java.com/java">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Output result]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2</bpmn2:incoming>
+            <bpmn2:outgoing>_D58996F7-7E62-469E-AA1B-98EAB4B1F79F</bpmn2:outgoing>
+            <bpmn2:script>System.out.println("Error result is = " + result);</bpmn2:script>
+        </bpmn2:scriptTask>
+        <bpmn2:serviceTask id="_387FB4E7-AE40-4069-B415-195615766F78" drools:serviceimplementation="Java" drools:serviceinterface="dev.unexist.showcase.todo.application.KogitoService" drools:serviceoperation="checkTodo" name="Check Todo" implementation="Java" operationRef="_387FB4E7-AE40-4069-B415-195615766F78_ServiceOperation">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Check Todo]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>SequenceFlow_1p2szow</bpmn2:incoming>
+            <bpmn2:outgoing>_2B2A9AE1-7A13-4CE5-BF9C-02E65D834923</bpmn2:outgoing>
+            <bpmn2:ioSpecification>
+                <bpmn2:dataInput id="_387FB4E7-AE40-4069-B415-195615766F78_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__387FB4E7-AE40-4069-B415-195615766F78_todoInputXItem" name="todo"/>
+                <bpmn2:dataOutput id="_387FB4E7-AE40-4069-B415-195615766F78_resultOutputX" drools:dtype="String" itemSubjectRef="__387FB4E7-AE40-4069-B415-195615766F78_resultOutputXItem" name="result"/>
+                <bpmn2:inputSet>
+                    <bpmn2:dataInputRefs>_387FB4E7-AE40-4069-B415-195615766F78_todoInputX</bpmn2:dataInputRefs>
+                </bpmn2:inputSet>
+                <bpmn2:outputSet>
+                    <bpmn2:dataOutputRefs>_387FB4E7-AE40-4069-B415-195615766F78_resultOutputX</bpmn2:dataOutputRefs>
+                </bpmn2:outputSet>
+            </bpmn2:ioSpecification>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_387FB4E7-AE40-4069-B415-195615766F78_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+            <bpmn2:dataOutputAssociation>
+                <bpmn2:sourceRef>_387FB4E7-AE40-4069-B415-195615766F78_resultOutputX</bpmn2:sourceRef>
+                <bpmn2:targetRef>result</bpmn2:targetRef>
+            </bpmn2:dataOutputAssociation>
+        </bpmn2:serviceTask>
+        <bpmn2:businessRuleTask id="_861122DB-2755-408E-A8CC-69F8CCC04E0F" drools:ruleFlowGroup="TodoUpdater" name="Set todo to done" implementation="http://www.jboss.org/drools/rule">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Set todo to done]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:incoming>_C0F5678E-4C29-4353-A7EB-5E09BB193172</bpmn2:incoming>
+            <bpmn2:outgoing>_5DD76EFC-AB2A-4D5A-80BB-BBD0F40847AA</bpmn2:outgoing>
+            <bpmn2:ioSpecification>
+                <bpmn2:dataInput id="_861122DB-2755-408E-A8CC-69F8CCC04E0F_todoInputX" drools:dtype="dev.unexist.showcase.todo.domain.todo.TodoBase" itemSubjectRef="__861122DB-2755-408E-A8CC-69F8CCC04E0F_todoInputXItem" name="todo"/>
+                <bpmn2:inputSet>
+                    <bpmn2:dataInputRefs>_861122DB-2755-408E-A8CC-69F8CCC04E0F_todoInputX</bpmn2:dataInputRefs>
+                </bpmn2:inputSet>
+            </bpmn2:ioSpecification>
+            <bpmn2:dataInputAssociation>
+                <bpmn2:sourceRef>todo</bpmn2:sourceRef>
+                <bpmn2:targetRef>_861122DB-2755-408E-A8CC-69F8CCC04E0F_todoInputX</bpmn2:targetRef>
+            </bpmn2:dataInputAssociation>
+        </bpmn2:businessRuleTask>
+        <bpmn2:exclusiveGateway id="_69803135-7AE7-4578-B094-EF4D1304143C" drools:dg="_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2" gatewayDirection="Diverging" default="_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2">
+            <bpmn2:incoming>_2B2A9AE1-7A13-4CE5-BF9C-02E65D834923</bpmn2:incoming>
+            <bpmn2:outgoing>_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2</bpmn2:outgoing>
+            <bpmn2:outgoing>_C0F5678E-4C29-4353-A7EB-5E09BB193172</bpmn2:outgoing>
+        </bpmn2:exclusiveGateway>
+        <bpmn2:startEvent id="StartEvent_1" name="Todo Retrieved">
+            <bpmn2:extensionElements>
+                <drools:metaData name="elementname">
+                    <drools:metaValue><![CDATA[Todo Retrieved]]></drools:metaValue>
+                </drools:metaData>
+            </bpmn2:extensionElements>
+            <bpmn2:outgoing>SequenceFlow_1p2szow</bpmn2:outgoing>
+        </bpmn2:startEvent>
+    </bpmn2:process>
+    <bpmndi:BPMNDiagram>
+        <bpmndi:BPMNPlane bpmnElement="kogito">
+            <bpmndi:BPMNShape id="shape_StartEvent_1" bpmnElement="StartEvent_1">
+                <dc:Bounds height="56" width="56" x="358" y="150"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__69803135-7AE7-4578-B094-EF4D1304143C" bpmnElement="_69803135-7AE7-4578-B094-EF4D1304143C">
+                <dc:Bounds height="56" width="56" x="749" y="150"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__861122DB-2755-408E-A8CC-69F8CCC04E0F" bpmnElement="_861122DB-2755-408E-A8CC-69F8CCC04E0F">
+                <dc:Bounds height="91" width="131" x="907" y="132"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__387FB4E7-AE40-4069-B415-195615766F78" bpmnElement="_387FB4E7-AE40-4069-B415-195615766F78">
+                <dc:Bounds height="102" width="154" x="493" y="127"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__656D38BC-B196-4069-B056-558680635036" bpmnElement="_656D38BC-B196-4069-B056-558680635036">
+                <dc:Bounds height="102" width="154" x="700" y="288"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__04769C15-8ED3-40CE-9C0F-D19A387474F2" bpmnElement="_04769C15-8ED3-40CE-9C0F-D19A387474F2">
+                <dc:Bounds height="56" width="56" x="934" y="311"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__D4613D07-712A-4548-B031-AE7D6EF5D21F" bpmnElement="_D4613D07-712A-4548-B031-AE7D6EF5D21F">
+                <dc:Bounds height="56" width="56" x="1596" y="150"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__4409773D-EF92-4DD3-8F6C-F952C27E8B1A" bpmnElement="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A">
+                <dc:Bounds height="102" width="154" x="1129" y="127"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__AE3769CC-FF77-4A34-A0DA-88DFD1767C4B" bpmnElement="_AE3769CC-FF77-4A34-A0DA-88DFD1767C4B">
+                <dc:Bounds height="102" width="154" x="1366" y="127"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6" bpmnElement="_AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6">
+                <dc:Bounds height="56" width="56" x="358" y="535"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__AEF1C263-7073-433A-8F35-A7C49A729B84" bpmnElement="_AEF1C263-7073-433A-8F35-A7C49A729B84">
+                <dc:Bounds height="102" width="154" x="480" y="512"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__38AF6677-7128-43AB-9552-3E1C822036FF" bpmnElement="_38AF6677-7128-43AB-9552-3E1C822036FF">
+                <dc:Bounds height="102" width="154" x="972" y="512"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA" bpmnElement="_6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA">
+                <dc:Bounds height="102" width="154" x="1218" y="512"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__386D55D9-CDD0-4EB3-93BC-99FBB3E538E1" bpmnElement="_386D55D9-CDD0-4EB3-93BC-99FBB3E538E1">
+                <dc:Bounds height="56" width="56" x="1464" y="535"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNShape id="shape__E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769" bpmnElement="_E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769">
+                <dc:Bounds height="102" width="154" x="726" y="512"/>
+            </bpmndi:BPMNShape>
+            <bpmndi:BPMNEdge id="edge_shape_StartEvent_1_to_shape__387FB4E7-AE40-4069-B415-195615766F78" bpmnElement="SequenceFlow_1p2szow">
+                <di:waypoint x="394" y="168"/>
+                <di:waypoint x="493" y="178"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__387FB4E7-AE40-4069-B415-195615766F78_to_shape__69803135-7AE7-4578-B094-EF4D1304143C" bpmnElement="_2B2A9AE1-7A13-4CE5-BF9C-02E65D834923">
+                <di:waypoint x="570" y="178"/>
+                <di:waypoint x="749" y="178"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__69803135-7AE7-4578-B094-EF4D1304143C_to_shape__656D38BC-B196-4069-B056-558680635036" bpmnElement="_AE2CFDCE-87E1-415D-9C50-3F6E52B331D2">
+                <di:waypoint x="777" y="206"/>
+                <di:waypoint x="777" y="288"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__69803135-7AE7-4578-B094-EF4D1304143C_to_shape__861122DB-2755-408E-A8CC-69F8CCC04E0F" bpmnElement="_C0F5678E-4C29-4353-A7EB-5E09BB193172">
+                <di:waypoint x="777" y="178"/>
+                <di:waypoint x="907" y="177.5"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__861122DB-2755-408E-A8CC-69F8CCC04E0F_to_shape__4409773D-EF92-4DD3-8F6C-F952C27E8B1A" bpmnElement="_5DD76EFC-AB2A-4D5A-80BB-BBD0F40847AA">
+                <di:waypoint x="972.5" y="177.5"/>
+                <di:waypoint x="1129" y="178"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__656D38BC-B196-4069-B056-558680635036_to_shape__04769C15-8ED3-40CE-9C0F-D19A387474F2" bpmnElement="_D58996F7-7E62-469E-AA1B-98EAB4B1F79F">
+                <di:waypoint x="777" y="339"/>
+                <di:waypoint x="962" y="339"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__AE3769CC-FF77-4A34-A0DA-88DFD1767C4B_to_shape__D4613D07-712A-4548-B031-AE7D6EF5D21F" bpmnElement="_EE2620C9-5B32-4C75-B0B7-689FA93CB842">
+                <di:waypoint x="1443" y="178"/>
+                <di:waypoint x="1596" y="178"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__4409773D-EF92-4DD3-8F6C-F952C27E8B1A_to_shape__AE3769CC-FF77-4A34-A0DA-88DFD1767C4B" bpmnElement="_2E37D9BC-CBC6-43FB-BB77-8A04589AC652">
+                <di:waypoint x="1206" y="178"/>
+                <di:waypoint x="1366" y="178"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__AA0DFE54-5F11-4C5E-B4E9-CAB6E6FA4EF6_to_shape__AEF1C263-7073-433A-8F35-A7C49A729B84" bpmnElement="_D20E2D87-6924-4D8B-9478-70C343074C18">
+                <di:waypoint x="386" y="563"/>
+                <di:waypoint x="480" y="563"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__AEF1C263-7073-433A-8F35-A7C49A729B84_to_shape__E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769" bpmnElement="_F08E870E-5755-4106-A1ED-6783E33A2B2F">
+                <di:waypoint x="557" y="563"/>
+                <di:waypoint x="726" y="563"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769_to_shape__38AF6677-7128-43AB-9552-3E1C822036FF" bpmnElement="_D7B776B2-1308-4C32-B610-17C625D90C4A">
+                <di:waypoint x="803" y="563"/>
+                <di:waypoint x="972" y="563"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__38AF6677-7128-43AB-9552-3E1C822036FF_to_shape__6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA" bpmnElement="_92A3E94E-3162-425D-AE15-1EA8C3D46535">
+                <di:waypoint x="1049" y="563"/>
+                <di:waypoint x="1218" y="563"/>
+            </bpmndi:BPMNEdge>
+            <bpmndi:BPMNEdge id="edge_shape__6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA_to_shape__386D55D9-CDD0-4EB3-93BC-99FBB3E538E1" bpmnElement="_8939AE84-7DC6-4DD1-8EAD-6A60C6628EE4">
+                <di:waypoint x="1295" y="563"/>
+                <di:waypoint x="1464" y="563"/>
+            </bpmndi:BPMNEdge>
+        </bpmndi:BPMNPlane>
+    </bpmndi:BPMNDiagram>
+    <bpmn2:relationship type="BPSimData">
+        <bpmn2:extensionElements>
+            <bpsim:BPSimData>
+                <bpsim:Scenario id="default" name="Simulationscenario">
+                    <bpsim:ScenarioParameters/>
+                    <bpsim:ElementParameters elementRef="StartEvent_1">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_861122DB-2755-408E-A8CC-69F8CCC04E0F">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_387FB4E7-AE40-4069-B415-195615766F78">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_656D38BC-B196-4069-B056-558680635036">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_4409773D-EF92-4DD3-8F6C-F952C27E8B1A">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_AE3769CC-FF77-4A34-A0DA-88DFD1767C4B">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_AEF1C263-7073-433A-8F35-A7C49A729B84">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_38AF6677-7128-43AB-9552-3E1C822036FF">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_6E56C5A5-8B38-4EC0-A2EC-B92E36873AAA">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                    <bpsim:ElementParameters elementRef="_E1F9D9BE-CB2D-41C0-82D6-2FDD7534C769">
+                        <bpsim:TimeParameters>
+                            <bpsim:ProcessingTime>
+                                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+                            </bpsim:ProcessingTime>
+                        </bpsim:TimeParameters>
+                        <bpsim:ResourceParameters>
+                            <bpsim:Availability>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Availability>
+                            <bpsim:Quantity>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:Quantity>
+                        </bpsim:ResourceParameters>
+                        <bpsim:CostParameters>
+                            <bpsim:UnitCost>
+                                <bpsim:FloatingParameter value="0"/>
+                            </bpsim:UnitCost>
+                        </bpsim:CostParameters>
+                    </bpsim:ElementParameters>
+                </bpsim:Scenario>
+            </bpsim:BPSimData>
+        </bpmn2:extensionElements>
+        <bpmn2:source>_ey7wMM32EDmwu7XcyDGIPQ</bpmn2:source>
+        <bpmn2:target>_ey7wMM32EDmwu7XcyDGIPQ</bpmn2:target>
+    </bpmn2:relationship>
+</bpmn2:definitions>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/main/resources/dev/unexist/showcase/todo/todo.drl	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,13 @@
+package dev.unexist.showcase.todo.adapter;
+dialect  "mvel"
+
+import dev.unexist.showcase.todo.domain.todo.TodoBase;
+
+rule "isDone" ruleflow-group "TodoUpdater"
+    when
+        $todo: TodoBase(done != true)
+    then
+        modify($todo) {
+            setDone(true)
+        }
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/todo-service-kogito-quarkus/src/test/java/dev/unexist/showcase/todo/application/TodoResourceTest.java	Mon Aug 16 17:33:16 2021 +0200
@@ -0,0 +1,29 @@
+/**
+ * @package Quarkus-Workflow-Showcase
+ *
+ * @file Stupid integration test
+ * @copyright 2020-2021 Christoph Kappel <christoph@unexist.dev>
+ * @version $Id$
+ *
+ * This program can be distributed under the terms of the Apache License v2.0.
+ * See the file LICENSE for details.
+ **/
+
+package dev.unexist.showcase.todo.application;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+
+@QuarkusTest
+public class TodoResourceTest {
+
+    @Test
+    public void testTodoEndpoint() {
+        given()
+          .when().get("/todo")
+          .then()
+             .statusCode(204);
+    }
+}
\ No newline at end of file