Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KOGITO-9454] Documenting java flow library #585

Merged
merged 14 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions serverlessworkflow/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Getting Started
** xref:getting-started/getting-familiar-with-our-tooling.adoc[]
** xref:getting-started/create-your-first-workflow-service-with-kn-cli-and-vscode.adoc[]
** xref:getting-started/java-embedded-workflows.adoc[]
* Core Concepts
** xref:core/cncf-serverless-workflow-specification-support.adoc[]
** xref:core/handling-events-on-workflows.adoc[Events]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
= Workflow embedded execution in Java

This guide show cases how to execute a link:{spec_doc_url}[CNCF Serverless Workflow] definition using a standard java virtual machine and a small set of Maven dependencies. Therefore, it is assumed you are fluent both in Java and Maven.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
The workflow definition to be executed can be read from a .json or .yaml file or programatically defined using the {product_name} fluent API.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

fjtirado marked this conversation as resolved.
Show resolved Hide resolved
[[embedded-file-quick-start]]
== Hello world (using existing definition file)

First step is to setup an empty Maven project with the following dependency.
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,xml]
----
<dependency>
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-serverless-workflow-executor-core</artifactId>
<version>RELEASE</version>
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
----

Also, you might optionally add `simple logger for java` dependency to avoid using `System.out.println`
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,xml]
----
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
----

Let's assume you already have a workflow definition written in a JSON file in your project root. For example, link:{kogito_sw_examples_url}/serverless-workflow-hello-world/src/main/resources/hello.sw.json[Hello World] definition. To execute it, you need to write the following main java class (standard imports and java package declaration are intentionally skipped for brevity)
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,java]
----
import org.kie.kogito.serverless.workflow.executor.StaticWorkflowApplication;
import org.kie.kogito.serverless.workflow.models.JsonNodeModel;
import org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils;
import org.kie.kogito.serverless.workflow.utils.WorkflowFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.serverlessworkflow.api.Workflow;

public class DefinitionFileExecutor {
private static final Logger logger = LoggerFactory.getLogger(DefinitionFileExecutor.class);

public static void main(String[] args) throws IOException {
try (Reader reader = new FileReader("hello.sw.json"); <1>
StaticWorkflowApplication application = StaticWorkflowApplication.create()) { <2>
Workflow workflow = ServerlessWorkflowUtils.getWorkflow(reader, WorkflowFormat.JSON); <3>
JsonNodeModel result = application.execute(workflow, Collections.emptyMap()); <4>
logger.info("Workflow execution result is {}", result.getWorkflowdata()); <5>
}
}
}
----
<1> Reads the workflow file definition from the project root directory
<2> Creates a static workflow application object. It is done within the try block since the instance is `Closeable`. This is the reference that allow you to execute workflow definitions.
<3> Reads the Serverless Workflow Java SDK `Workflow` object from the file.
<4> Execute the workflow, passing `Workflow` reference and no parameters (an empty Map). The result of the workflow execution: process instance id and workflow output model, can accessed using `result` variable.
<5> Prints the workflow model in the configured standard output.

If you compile and execute this java class, you will see the following log in your configured standard output
fjtirado marked this conversation as resolved.
Show resolved Hide resolved
----
Workflow execution result is {"greeting":"Hello World","mantra":"Serverless Workflow is awesome!"}
----

[[embedded-fluent-quick-start]]
== Hello world (using fluent API)

Using the same Maven setup than in the previous section, you can programatically generate that workflow definition rather than loading it from a file definition by using link:{kogito_runtimes_url}/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent[fluent API]
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

Therefore, you can modify the previous example in a way that generates exactly the same output when it is executed, but rather creating a `FileReader` that reads the `Workflow` object, we create the `Workflow` object using java statements. The resulting modified main method is the following
fjtirado marked this conversation as resolved.
Show resolved Hide resolved

[source,java]
----
try (StaticWorkflowApplication application = StaticWorkflowApplication.create()) {
Workflow workflow = workflow("HelloWorld"). <1>
start( <2>
inject( <3>
jsonObject().put("greeting", "Hello World").put("mantra","Serverless Workflow is awesome!"))) <4>
.end() <5>
.build(); <6>
logger.info("Workflow execution result is {}",application.execute(workflow, Collections.emptyMap()).getWorkflowdata()); <7>
}
----
<1> Creates a workflow which name is `HelloWorld`
<2> Indicate that you are going to specify the start state
<3> A Inject state is the start state
<4> Inject state accepts static json, therefore this line creates the JSON data
<5> End the workflow definition
<6> Build the workflow definition
<7> Execute and print as in previous example


== Further reading

You can find additional and commented examples of fluent API usage (including jq expression evaluation and orchestration of rest services) link:{{kogito_sw_examples_url}/sonata-workflow-fluent[here]

== Additional resources

include::../../pages/_common-content/report-issue.adoc[]

ifeval::["{kogito_version_redhat}" != ""]
include::../../pages/_common-content/downstream-project-setup-instructions.adoc[]
endif::[]
8 changes: 8 additions & 0 deletions serverlessworkflow/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ xref:getting-started/create-your-first-workflow-service-with-kn-cli-and-vscode.a
An all-in-one starting guide. Learn how to create, run & deploy your first {product_name} project on your local environment.
--

[.card]
--
[.card-title]
xref:getting-started/java-embedded-workflows.adoc[]
[.card-description]
Learn about how to executed your workflows (existing files or define them programatically) using Java and Maven.
--

[.card-section]
== Core Concepts

Expand Down