This is an automated email from the ASF dual-hosted git repository.

fjtiradosarti pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-examples.git


The following commit(s) were added to refs/heads/main by this push:
     new eb9e770ac Add MongoDB correlation on Quarkus example (#1999)
eb9e770ac is described below

commit eb9e770ac285e36df14e35ad80cb4146c5cf1ea9
Author: Matheus Cruz <[email protected]>
AuthorDate: Tue Oct 1 11:27:27 2024 -0300

    Add MongoDB correlation on Quarkus example (#1999)
    
    * Add mongodb correlation for Quarkus example
    
    * Add mongodb example pom.xml
    
    * Adjust parent pom.xml
---
 README.md                                          |   6 +
 serverless-workflow-examples/pom.xml               |   1 +
 .../README.md                                      | 154 ++++++++++++++++
 .../docker-compose/docker-compose.yml              |  85 +++++++++
 .../pom.xml                                        | 199 +++++++++++++++++++++
 .../main/java/org/kie/kogito/examples/Account.java |  41 +++++
 .../org/kie/kogito/examples/EventsService.java     | 106 +++++++++++
 .../org/kie/kogito/examples/WorkflowResource.java  |  85 +++++++++
 .../src/main/resources/application.properties      | 101 +++++++++++
 .../src/main/resources/correlation.sw.json         | 104 +++++++++++
 .../org/kie/kogito/examples/CorrelationIT.java     |  91 ++++++++++
 .../src/test/resources/application.properties      |  24 +++
 12 files changed, 997 insertions(+)

diff --git a/README.md b/README.md
index 4cc8f4fb1..0ac337716 100644
--- a/README.md
+++ b/README.md
@@ -141,6 +141,12 @@ A Serverless Workflow service that works as a Github bot 
application, which reac
 
 * [on 
Quarkus](serverless-workflow-examples/serverless-workflow-github-showcase)
 
+## Serverless Workflow Correlation
+
+* [on Quarkus 
(JDBC)](serverless-workflow-examples/serverless-workflow-correlation-quarkus)
+* [on Quarkus 
(MongoDB)](serverless-workflow-examples/serverless-workflow-correlation-mongodb-quarkus)
+
+
 ## Other Misc Examples
 
 - Onboarding example combining 1 process and two decision services: see 
[README.md](kogito-quarkus-examples/onboarding-example/README.md)
diff --git a/serverless-workflow-examples/pom.xml 
b/serverless-workflow-examples/pom.xml
index 962cbd298..c9bb9cf6f 100644
--- a/serverless-workflow-examples/pom.xml
+++ b/serverless-workflow-examples/pom.xml
@@ -49,6 +49,7 @@
         <module>serverless-workflow-compensation-quarkus</module>
         <module>serverless-workflow-consuming-events-over-http-quarkus</module>
         <module>serverless-workflow-correlation-quarkus</module>
+        <module>serverless-workflow-correlation-quarkus-mongodb</module>
         <module>serverless-workflow-custom-function-knative</module>
         <module>serverless-workflow-custom-type</module>
         
<module>serverless-workflow-data-index-persistence-addon-quarkus</module>
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/README.md
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/README.md
new file mode 100644
index 000000000..d901964f7
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/README.md
@@ -0,0 +1,154 @@
+# Kogito Serverless Workflow - Correlation with Callback Example
+
+## Description
+
+This example contains a workflow service to demonstrate correlation feature 
using callback states and events. 
+Each callback state withing the workflow publishes an event and wait for a 
response event, 
+there is an incoming event, it is matched with the proper workflow instance by 
using the correlation attribute, in this case it is the `userid`. So for every 
incoming event the userid is used to properly find and trigger the proper 
workflow instance. The correlation is defined in the [workflow definition 
file](src/main/resources/correlation.sw.json) that is described using JSON 
format as defined in the [CNCF Serverless Workflow 
specification](https://github.com/serverlessworkflow/specifi [...]
+
+```json
+"correlation": [
+    {
+    "contextAttributeName": "userid"
+    }
+]
+```
+Events should be in CloudEvent format and the correlation attribute should be 
defined as an extension attribute, in this case `userid`.
+
+The workflow example is started by events as well, so a start event should be 
published with the same correlation attribute `userid, that will be used to 
match correlations for the started workflow instance. 
+ 
+In the example the event broker used to publish/receive the events is Kafka, 
and the used topics are the same described as the event types in the workflow 
definition.
+
+
+```json
+{
+  "name": "newAccountEvent",
+  "source": "",
+  "type": "newAccountEventType",
+  "correlation": [
+    {
+      "contextAttributeName": "userid"
+    }
+  ]
+}
+```
+For simplicity, the events are published and consumed in the same application 
running the workflow, but in a real use case they should come from different 
services interacting with the workflow, see 
[EventsService](src/main/java/org/kie/kogito/examples/EventsService.java).
+
+To start the workflow as mentioned, it is required an event to be published 
which is going to be consumed by the workflow service starting a new instance. 
A helper REST endpoint was recreated to simplify this step, so once a POST 
request is received it publishes the start event to the broker see 
[WorkflowResource](src/main/java/org/kie/kogito/examples/WorkflowResource.java).
+
+All eventing configuration and the broker parameters are in done in the 
[application.properties](src/main/resources/application.properties). 
+
+## Infrastructure requirements
+
+### Kafka
+
+This quickstart requires an Apache Kafka to be available and by default 
expects it to be on default port and localhost.
+
+* Install and Startup Kafka Server / Zookeeper
+
+https://kafka.apache.org/quickstart
+
+To publish and consume the event, topic "move" is used. 
+
+Optionally and for convenience, a docker-compose [configuration 
file](docker-compose/docker-compose.yml) is
+provided in the path [docker-compose/](docker-compose/), where you can just 
run the command from there:
+
+```sh
+docker-compose up
+```
+
+In this way a container for Kafka will be started on port 9092.
+
+### MongoDB
+
+Alternatively, you can run this example using persistence with a MongoDB 
server.
+
+Configuration for setting up the connection can be found in 
[applications.properties](src/main/resources/application.properties) file, which
+follows the Quarkus MongoDB Client settings, for more information please check 
[MongoDB Client Configuration 
Reference](https://quarkus.io/guides/mongodb#configuration-reference).
+
+Optionally and for convenience, a docker-compose [configuration 
file](docker-compose/docker-compose.yml) is
+provided in the path [docker-compose/](docker-compose/), where you can just 
run the command from there:
+
+```sh
+docker-compose up
+```
+
+## Installing and Running
+
+### Prerequisites
+ 
+You will need:
+  - Java 17+ installed
+  - Environment variable JAVA_HOME set accordingly
+  - Maven 3.9.6+ installed
+
+When using native image compilation, you will also need: 
+  - [GraalVm](https://www.graalvm.org/downloads/) 19.3.1+ installed
+  - Environment variable GRAALVM_HOME set accordingly
+  - Note that GraalVM native image compilation typically requires other 
packages (glibc-devel, zlib-devel and gcc) to be installed too.  You also need 
'native-image' installed in GraalVM (using 'gu install native-image'). Please 
refer to [GraalVM installation 
documentation](https://www.graalvm.org/docs/reference-manual/aot-compilation/#prerequisites)
 for more details.
+
+### Compile and Run in Local Dev Mode
+
+```sh
+mvn clean package quarkus:dev
+```
+
+### Compile and Run in JVM mode
+
+```sh
+mvn clean package 
+java -jar target/quarkus-app/quarkus-run.jar
+```
+
+or on Windows
+
+```sh
+mvn clean package
+java -jar target\quarkus-app\quarkus-run.jar
+```
+
+### Compile and Run in JVM mode using PostgreSQL persistence
+
+To enable persistence, please append `-Ppersistence` to your Maven command.
+That will ensure the correct dependencies are in place, and automatically set 
the required properties to connect
+with the PostgreSQL instance from the provided docker compose.
+
+```sh
+mvn clean package -Peristence 
+```
+
+### Compile and Run using Local Native Image
+Note that this requires GRAALVM_HOME to point to a valid GraalVM installation
+
+```sh
+mvn clean package -Pnative
+```
+  
+To run the generated native executable, generated in `target/`, execute
+
+```sh
+./target/serverless-workflow-correlation-quarkus-{version}-runner
+```
+
+### Start a workflow
+
+The service based on the JSON workflow definition can be access by sending a 
request to http://localhost:8080/account/{userid}
+
+Complete curl command can be found below:
+
+```sh
+curl -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 
http://localhost:8080/account/12345
+```
+
+After a while (note that to you need give time for event to be consumed)  you 
should see the log message printed in the console, and the workflow is 
completed.
+
+```text
+2022-05-12 11:02:15,891 INFO  [org.kie.kog.ser.eve.imp.ProcessEventDispatcher] 
(kogito-event-executor-0) Starting new process instance with signal 
'newAccountEventType'
+2022-05-12 11:02:18,909 INFO  [io.sma.rea.mes.kafka] 
(vert.x-eventloop-thread-9) SRMSG18256: Initialize record store for 
topic-partition 'validateAccountEmail-0' at position 16.
+2022-05-12 11:02:18,919 INFO  [org.kie.kog.exa.EventsService] 
(pool-1-thread-1) Validate Account received. Workflow data 
JsonCloudEventData{node={"email":"[email protected]","userId":"12345"}}
+2022-05-12 11:02:19,931 INFO  [io.sma.rea.mes.kafka] 
(vert.x-eventloop-thread-5) SRMSG18256: Initialize record store for 
topic-partition 'validatedAccountEmail-0' at position 16.
+2022-05-12 11:02:20,962 INFO  [io.sma.rea.mes.kafka] 
(vert.x-eventloop-thread-8) SRMSG18256: Initialize record store for 
topic-partition 'activateAccount-0' at position 16.
+2022-05-12 11:02:20,971 INFO  [org.kie.kog.exa.EventsService] 
(pool-1-thread-1) Activate Account received. Workflow data 
JsonCloudEventData{node={"email":"[email protected]","userId":"12345"}}
+2022-05-12 11:02:21,994 INFO  [io.sma.rea.mes.kafka] 
(vert.x-eventloop-thread-6) SRMSG18256: Initialize record store for 
topic-partition 'activatedAccount-0' at position 7.
+2022-05-12 11:02:22,006 INFO  [org.kie.kog.exa.EventsService] 
(kogito-event-executor-0) Complete Account Creation received. Workflow data 
{"email":"[email protected]","userId":"12345"}, KogitoProcessInstanceId 
0cef0eef-06c8-4433-baea-505fa8d45f68 
+```
\ No newline at end of file
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/docker-compose/docker-compose.yml
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/docker-compose/docker-compose.yml
new file mode 100644
index 000000000..24ea2caf8
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/docker-compose/docker-compose.yml
@@ -0,0 +1,85 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+version: "3"
+
+services:
+  zookeeper:
+    container_name: zookeeper
+    image: strimzi/kafka:0.20.1-kafka-2.6.0
+    command: [
+        "sh", "-c",
+        "bin/zookeeper-server-start.sh config/zookeeper.properties"
+    ]
+    ports:
+      - "2181:2181"
+    environment:
+      LOG_DIR: "/tmp/logs"
+
+  kafka:
+    image: strimzi/kafka:0.20.1-kafka-2.6.0
+    container_name: kafka
+    command: [
+        "sh", "-c",
+        "bin/kafka-server-start.sh config/server.properties --override 
inter.broker.listener.name=$${KAFKA_INTER_BROKER_LISTENER_NAME} --override 
listener.security.protocol.map=$${KAFKA_LISTENER_SECURITY_PROTOCOL_MAP} 
--override listeners=$${KAFKA_LISTENERS} --override 
advertised.listeners=$${KAFKA_ADVERTISED_LISTENERS} --override 
zookeeper.connect=$${KAFKA_ZOOKEEPER_CONNECT}"
+    ]
+    depends_on:
+      - zookeeper
+    ports:
+      - "9092:9092"
+    environment:
+      KAFKA_BROKER_ID: 0
+      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
+      KAFKA_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://kafka:9092
+      KAFKA_ADVERTISED_LISTENERS: 
INTERNAL://kafka:29092,EXTERNAL://localhost:9092
+      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 
INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
+      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
+      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
+      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+      LOG_DIR: "/tmp/logs"
+
+  mongodb:
+    image: mongo:latest
+    restart: always
+    container_name: mongo
+    ports:
+      - "27017:27017"
+    networks:
+      - mongodb-compose-network
+  mongo-express:
+    image: mongo-express:latest
+    container_name: mongo_express
+    environment:
+      ME_CONFIG_MONGODB_ADMINUSERNAME: root
+      ME_CONFIG_MONGODB_ADMINPASSWORD: example
+      ME_CONFIG_MONGODB_URL: mongodb://mongo:27017/
+      ME_CONFIG_BASICAUTH: false
+    ports:
+      - "8081:8081"
+    depends_on:
+      - mongodb
+    networks:
+      - mongodb-compose-network
+
+networks:
+  mongodb-compose-network:
+    driver: bridge
+
+
+#     curl -X POST -H 'Content-Type:application/json' -H 
'Accept:application/json' http://localhost:8888/account/mirror &&  curl -X POST 
-H 'Content-Type:application/json' -H 'Accept:application/json' 
http://localhost:8080/account/mirror
\ No newline at end of file
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/pom.xml
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/pom.xml
new file mode 100644
index 000000000..07e78a31d
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/pom.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://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>
+
+  <parent>
+    <groupId>org.kie.kogito.examples</groupId>
+    <artifactId>serverless-workflow-examples-parent</artifactId>
+    <version>999-SNAPSHOT</version>
+    <relativePath>../serverless-workflow-examples-parent/pom.xml</relativePath>
+  </parent>
+
+  <groupId>org.kie.kogito.examples</groupId>
+  <artifactId>serverless-workflow-correlation-quarkus-mongodb</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <name>Kogito Example :: Serverless Workflow Correlation :: Quarkus :: 
MongoDB</name>
+  <description>Kogito Serverless Workflow Correlation Example - Quarkus - 
MongoDB</description>
+  <properties>
+    <quarkus-plugin.version>3.8.4</quarkus-plugin.version>
+    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
+    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
+    <quarkus.platform.version>3.8.4</quarkus.platform.version>
+    <kogito.bom.group-id>org.kie.kogito</kogito.bom.group-id>
+    <kogito.bom.artifact-id>kogito-bom</kogito.bom.artifact-id>
+    <kogito.bom.version>999-SNAPSHOT</kogito.bom.version>
+    <version.compiler.plugin>3.8.1</version.compiler.plugin>
+    <maven.compiler.release>17</maven.compiler.release>
+    <version.failsafe.plugin>3.0.0-M7</version.failsafe.plugin>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>${quarkus.platform.group-id}</groupId>
+        <artifactId>${quarkus.platform.artifact-id}</artifactId>
+        <version>${quarkus.platform.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>${kogito.bom.group-id}</groupId>
+        <artifactId>${kogito.bom.artifact-id}</artifactId>
+        <version>${kogito.bom.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.kie.sonataflow</groupId>
+      <artifactId>sonataflow-quarkus</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.kie</groupId>
+      <artifactId>kie-addons-quarkus-messaging</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-resteasy</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-resteasy-jackson</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-smallrye-health</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.kie</groupId>
+      <artifactId>kie-addons-quarkus-source-files</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>io.quarkus</groupId>
+      <artifactId>quarkus-junit5</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.rest-assured</groupId>
+      <artifactId>rest-assured</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <finalName>${project.artifactId}</finalName>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>${version.compiler.plugin}</version>
+        <configuration>
+          <release>${maven.compiler.release}</release>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>${quarkus.platform.group-id}</groupId>
+        <artifactId>quarkus-maven-plugin</artifactId>
+        <version>${quarkus-plugin.version}</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <goals>
+              <goal>build</goal>
+              <goal>generate-code</goal>
+              <goal>generate-code-tests</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <version>${version.failsafe.plugin}</version>
+        <configuration>
+          <systemPropertyVariables>
+            
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
+            <maven.home>${maven.home}</maven.home>
+          </systemPropertyVariables>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>integration-test</goal>
+              <goal>verify</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>container</id>
+      <activation>
+        <property>
+          <name>container</name>
+        </property>
+      </activation>
+      <properties>
+        <quarkus.profile>container</quarkus.profile>
+      </properties>
+      <dependencies>
+        <dependency>
+          <groupId>io.quarkus</groupId>
+          <artifactId>quarkus-container-image-jib</artifactId>
+        </dependency>
+      </dependencies>
+    </profile>
+    <profile>
+      <id>persistence</id>
+      <activation>
+        <property>
+          <name>persistence</name>
+        </property>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.kie</groupId>
+          <artifactId>kie-addons-quarkus-persistence-mongodb</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>io.quarkus</groupId>
+          <artifactId>quarkus-mongodb-client</artifactId>
+        </dependency>
+      </dependencies>
+    </profile>
+  </profiles>
+</project>
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/Account.java
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/Account.java
new file mode 100644
index 000000000..5da1f5754
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/Account.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.examples;
+
+public class Account {
+
+    private String email;
+    private String userId;
+
+    public Account() {
+    }
+
+    public Account(String email, String userId) {
+        this.email = email;
+        this.userId = userId;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+}
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/EventsService.java
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/EventsService.java
new file mode 100644
index 000000000..004e81d95
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/EventsService.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.examples;
+
+import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+
+import org.eclipse.microprofile.reactive.messaging.Acknowledgment;
+import org.eclipse.microprofile.reactive.messaging.Acknowledgment.Strategy;
+import org.eclipse.microprofile.reactive.messaging.Incoming;
+import org.eclipse.microprofile.reactive.messaging.Message;
+import org.eclipse.microprofile.reactive.messaging.Outgoing;
+import org.kie.kogito.event.cloudevents.utils.CloudEventUtils;
+import org.kie.kogito.internal.process.runtime.KogitoProcessContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import io.cloudevents.jackson.JsonCloudEventData;
+
+@ApplicationScoped
+public class EventsService {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(EventsService.class);
+
+    @Inject
+    ObjectMapper objectMapper;
+
+    private Map<String, String> accounts = new ConcurrentHashMap<>();
+
+    public void complete(JsonNode workflowData, KogitoProcessContext context) {
+        logger.info("Complete Account Creation received. Workflow data {}, 
KogitoProcessInstanceId {} ", workflowData, 
context.getProcessInstance().getStringId());
+    }
+
+    @Incoming("validate")
+    @Outgoing("validated")
+    @Acknowledgment(Strategy.POST_PROCESSING)
+    public String onEventValidate(Message<String> message) {
+        Optional<CloudEvent> ce = CloudEventUtils.decode(message.getPayload());
+        JsonCloudEventData cloudEventData = (JsonCloudEventData) 
ce.get().getData();
+        logger.info("Validate Account received. Workflow data {}", 
cloudEventData);
+        String userId = ce.get().getExtension("userid").toString();
+
+        //just for testing
+        accounts.put(userId, 
ce.get().getExtension("kogitoprocinstanceid").toString());
+
+        return generateCloudEvent(userId, "validatedAccountEmail", null);
+    }
+
+    @Incoming("activate")
+    @Outgoing("activated")
+    @Acknowledgment(Strategy.POST_PROCESSING)
+    public String onEventActivate(Message<String> message) {
+        Optional<CloudEvent> ce = CloudEventUtils.decode(message.getPayload());
+        JsonCloudEventData cloudEventData = (JsonCloudEventData) 
ce.get().getData();
+        logger.info("Activate Account received. Workflow data {}", 
cloudEventData);
+        return generateCloudEvent(ce.get().getExtension("userid").toString(), 
"activatedAccount", null);
+    }
+
+    private String generateCloudEvent(String id, String type, Object data) {
+        try {
+            return objectMapper.writeValueAsString(CloudEventBuilder.v1()
+                    .withId(UUID.randomUUID().toString())
+                    .withSource(URI.create(""))
+                    .withType(type)
+                    .withTime(OffsetDateTime.now())
+                    .withExtension("userid", id)
+                    .withData(objectMapper.writeValueAsBytes(data))
+                    .build());
+        } catch (JsonProcessingException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    public final String getAccount(String userId) {
+        return accounts.get(userId);
+    }
+}
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/WorkflowResource.java
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/WorkflowResource.java
new file mode 100644
index 000000000..de6af279a
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/java/org/kie/kogito/examples/WorkflowResource.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.examples;
+
+import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.Response;
+
+import org.eclipse.microprofile.reactive.messaging.Channel;
+import org.eclipse.microprofile.reactive.messaging.Emitter;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.cloudevents.core.builder.CloudEventBuilder;
+
+/**
+ * Helper class used to facilitate testing using REST
+ */
+@Path("/account")
+public class WorkflowResource {
+
+    @Inject
+    ObjectMapper objectMapper;
+
+    @Channel("start")
+    Emitter<String> emitter;
+
+    @Inject
+    EventsService eventsService;
+
+    @POST
+    @Path("/{userId}")
+    public Response onEvent(@PathParam("userId") String userId) {
+        String start = generateCloudEvent(userId, "newAccountEventType");
+        emitter.send(start);
+        return Response.status(Response.Status.CREATED).build();
+    }
+
+    @GET
+    @Path("/{userId}")
+    public Map<String, String> getProcessInstanceId(@PathParam("userId") 
String userId) {
+        return Collections.singletonMap("processInstanceId", 
eventsService.getAccount(userId));
+    }
+
+    private String generateCloudEvent(String id, String type) {
+        try {
+            return objectMapper.writeValueAsString(CloudEventBuilder.v03()
+                    .withId(UUID.randomUUID().toString())
+                    .withSource(URI.create(""))
+                    .withType(type)
+                    .withTime(OffsetDateTime.now())
+                    .withExtension("userid", id)
+                    .withData(objectMapper.writeValueAsBytes(new 
Account("[email protected]", id)))
+                    .build());
+        } catch (JsonProcessingException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/application.properties
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/application.properties
new file mode 100644
index 000000000..2996230c5
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/application.properties
@@ -0,0 +1,101 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+%prod.kafka.bootstrap.servers=localhost:9092
+
+#start the workflow events
+##application channels
+mp.messaging.outgoing.start.connector=smallrye-kafka
+mp.messaging.outgoing.start.topic=newAccountEventType
+mp.messaging.outgoing.start.value.serializer=org.apache.kafka.common.serialization.StringSerializer
+mp.messaging.outgoing.start.group.id=kogito-sw-callback
+
+##workflow channels
+mp.messaging.incoming.newAccountEventType.connector=smallrye-kafka
+mp.messaging.incoming.newAccountEventType.topic=newAccountEventType
+mp.messaging.incoming.newAccountEventType.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+mp.messaging.incoming.newAccountEventType.group.id=kogito-sw-callback
+mp.messaging.incoming.newAccountEventType.auto.offset.reset=earliest
+
+#activate account events
+##application channels
+mp.messaging.outgoing.activated.connector=smallrye-kafka
+mp.messaging.outgoing.activated.value.serializer=org.apache.kafka.common.serialization.StringSerializer
+mp.messaging.outgoing.activated.topic=activatedAccount
+mp.messaging.outgoing.activated.group.id=kogito-sw-callback
+
+mp.messaging.incoming.activate.connector=smallrye-kafka
+mp.messaging.incoming.activate.topic=activateAccount
+mp.messaging.incoming.activate.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+mp.messaging.incoming.activate.group.id=kogito-sw-callback
+mp.messaging.incoming.activate.auto.offset.reset=earliest
+
+##workflow channels
+mp.messaging.incoming.activatedAccount.connector=smallrye-kafka
+mp.messaging.incoming.activatedAccount.topic=activatedAccount
+mp.messaging.incoming.activatedAccount.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+mp.messaging.incoming.activatedAccount.group.id=kogito-sw-callback
+mp.messaging.incoming.activatedAccount.auto.offset.reset=earliest
+
+mp.messaging.outgoing.activateAccount.connector=smallrye-kafka
+mp.messaging.outgoing.activateAccount.value.serializer=org.apache.kafka.common.serialization.StringSerializer
+mp.messaging.outgoing.activateAccount.topic=activateAccount
+mp.messaging.outgoing.activateAccount.group.id=kogito-sw-callback
+
+#validate email events
+##application channels
+mp.messaging.incoming.validate.connector=smallrye-kafka
+mp.messaging.incoming.validate.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+mp.messaging.incoming.validate.topic=validateAccountEmail
+mp.messaging.incoming.validate.group.id=kogito-sw-callback
+mp.messaging.incoming.validate.auto.offset.reset=earliest
+
+mp.messaging.outgoing.validated.connector=smallrye-kafka
+mp.messaging.outgoing.validated.topic=validatedAccountEmail
+mp.messaging.outgoing.validated.value.serializer=org.apache.kafka.common.serialization.StringSerializer
+mp.messaging.outgoing.validated.group.id=kogito-sw-callback
+
+##workflow channels
+mp.messaging.outgoing.validateAccountEmail.connector=smallrye-kafka
+mp.messaging.outgoing.validateAccountEmail.topic=validateAccountEmail
+mp.messaging.outgoing.validateAccountEmail.value.serializer=org.apache.kafka.common.serialization.StringSerializer
+mp.messaging.outgoing.validateAccountEmail.group.id=kogito-sw-callback
+
+mp.messaging.incoming.validatedAccountEmail.connector=smallrye-kafka
+mp.messaging.incoming.validatedAccountEmail.value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
+mp.messaging.incoming.validatedAccountEmail.topic=validatedAccountEmail
+mp.messaging.incoming.validatedAccountEmail.group.id=kogito-sw-callback
+mp.messaging.incoming.validatedAccountEmail.auto.offset.reset=earliest
+
+#Persistence configuration
+kogito.persistence.type=mongodb
+
+quarkus.mongodb.database=kogito
+%prod.quarkus.mongodb.database=kogito
+
+kogito.persistence.proto.marshaller=true
+
+quarkus.grpc.dev-mode.force-server-start=false
+
+# profile to pack this example into a container, to use it execute activate 
the maven container profile, -Dcontainer
+%container.quarkus.container-image.build=true
+%container.quarkus.container-image.push=false
+%container.quarkus.container-image.group=${USER}
+%container.quarkus.container-image.registry=dev.local
+%container.quarkus.container-image.tag=1.0-SNAPSHOT
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/correlation.sw.json
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/correlation.sw.json
new file mode 100644
index 000000000..b6a44aeb1
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/main/resources/correlation.sw.json
@@ -0,0 +1,104 @@
+{
+  "id": "correlation",
+  "version": "1.0",
+  "name": "Workflow Correlation example",
+  "description": "An example of how to use correlation on events",  
+  "start": "New User Account Request",
+  "events": [
+    {
+      "name": "newAccountEvent",
+      "source": "",
+      "type": "newAccountEventType",
+      "correlation": [
+        {
+          "contextAttributeName": "userid"
+        }
+      ]      
+    },
+    {
+      "name": "validateAccountEmailEvent",
+      "source": "workflow",
+      "type": "validateAccountEmail"      
+    },
+    {
+      "name": "validatedAccountEmailEvent",
+      "source": "workflow",
+      "type": "validatedAccountEmail",
+      "correlation": [
+        {
+          "contextAttributeName": "userid"
+        }
+      ]      
+    },
+    {
+      "name": "activateAccountEvent",
+      "source": "workflow",
+      "type": "activateAccount"      
+    },
+    {
+      "name": "activatedAccountEvent",
+      "source": "workflow",
+      "type": "activatedAccount",
+      "correlation": [
+        {
+          "contextAttributeName": "userid"
+        }
+      ]      
+    }
+  ],
+  "functions": [
+    {
+      "name": "complete",
+      "type": "custom",
+      "operation": 
"service:java:org.kie.kogito.examples.EventsService::complete"
+    }
+  ],
+  "states": [
+     {
+     "name":"New User Account Request",
+     "type":"event",
+     "onEvents": [{
+         "eventRefs": ["newAccountEvent"]                 
+     }],     
+     "transition": "Validate User Email"
+  },
+    {
+      "name": "Validate User Email",
+      "type": "callback",
+      "action": {
+        "name": "publish validate event",
+        "eventRef": {
+          "triggerEventRef": "validateAccountEmailEvent"
+        }
+      },
+      "eventRef": "validatedAccountEmailEvent",      
+      "transition": "Activate User Account"
+    },
+{
+      "name": "Activate User Account",
+      "type": "callback",
+      "action": {
+        "name": "publish Activate Account event",
+        "eventRef": {
+          "triggerEventRef": "activateAccountEvent"          
+        }
+      },
+      "eventRef": "activatedAccountEvent",      
+      "transition": "Account Creation Completed"
+    },
+
+    {
+      "name": "Account Creation Completed",
+      "type": "operation",
+      "actions": [
+        {
+          "name": "accountCreationCompleted",
+          "functionRef": {
+            "refName": "complete"
+          }
+        }
+      ],
+      "end": true
+    }
+  ]
+}
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/java/org/kie/kogito/examples/CorrelationIT.java
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/java/org/kie/kogito/examples/CorrelationIT.java
new file mode 100644
index 000000000..9f8a24fcb
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/java/org/kie/kogito/examples/CorrelationIT.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.examples;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+import io.restassured.http.ContentType;
+
+import static io.restassured.RestAssured.given;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.Matchers.notNullValue;
+
+@QuarkusIntegrationTest
+class CorrelationIT {
+
+    public static final String HEALTH_URL = "/q/health";
+    public static final int TIMEOUT = 2;
+
+    private String userId = "12345";
+
+    @Test
+    void testCorrelation() {
+        //health check - wait to be ready
+        await()
+                .atMost(TIMEOUT, MINUTES)
+                .pollDelay(2, SECONDS)
+                .pollInterval(1, SECONDS)
+                .untilAsserted(() -> given()
+                        .contentType(ContentType.JSON)
+                        .accept(ContentType.JSON)
+                        .get(HEALTH_URL)
+                        .then()
+                        .statusCode(200));
+
+        //start workflow
+        given()
+                .contentType(ContentType.JSON)
+                .accept(ContentType.JSON)
+                .pathParam("userId", userId)
+                .post("/account/{userId}")
+                .then()
+                .statusCode(201);
+
+        //check instance created
+        AtomicReference<String> processInstanceId = new AtomicReference<>();
+        await().atMost(TIMEOUT, MINUTES)
+                .pollInterval(1, SECONDS)
+                .untilAsserted(() -> processInstanceId.set(given()
+                        .accept(ContentType.JSON)
+                        .pathParam("userId", userId)
+                        .get("/account/{userId}")
+                        .then()
+                        .statusCode(200)
+                        .body("processInstanceId", notNullValue())
+                        .extract()
+                        .body().path("processInstanceId")));
+
+        //check instance completed
+        await()
+                .atMost(TIMEOUT, MINUTES)
+                .pollInterval(1, SECONDS)
+                .untilAsserted(() -> given()
+                        .contentType(ContentType.JSON)
+                        .accept(ContentType.JSON)
+                        .pathParam("processInstanceId", 
processInstanceId.get())
+                        .get("/correlation/{processInstanceId}")
+                        .then()
+                        .statusCode(404));
+    }
+}
diff --git 
a/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/resources/application.properties
 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/resources/application.properties
new file mode 100644
index 000000000..50bf6c115
--- /dev/null
+++ 
b/serverless-workflow-examples/serverless-workflow-correlation-quarkus-mongodb/src/test/resources/application.properties
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Quarkus
+quarkus.http.test-port=0
+
+# Temporary fix for test to pass due to issue in Quarkus classloading resolver
+quarkus.class-loading.parent-first-artifacts=org.testcontainers:testcontainers
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to