Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package io.quarkiverse.flow.deployment;

import io.quarkiverse.flow.devui.InMemoryWorkflowInstanceStore;
import io.quarkiverse.flow.devui.InjectManagementListenerRecorder;
import io.quarkiverse.flow.devui.ManagementLifecycleListener;
import io.quarkiverse.flow.devui.ManagementLifecycleRPCService;
import io.quarkiverse.flow.devui.WorkflowRPCService;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.IsLocalDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;
import io.quarkus.devui.spi.page.CardPageBuildItem;
import io.quarkus.devui.spi.page.Page;
Expand All @@ -28,7 +36,24 @@ CardPageBuildItem card() {
}

@BuildStep(onlyIf = IsLocalDevelopment.class)
JsonRPCProvidersBuildItem createJsonRPCProviders() {
return new JsonRPCProvidersBuildItem(WorkflowRPCService.class);
void createJsonRPCProviders(BuildProducer<JsonRPCProvidersBuildItem> rpcProviders) {
rpcProviders.produce(new JsonRPCProvidersBuildItem(WorkflowRPCService.class));
rpcProviders.produce(new JsonRPCProvidersBuildItem(ManagementLifecycleRPCService.class));
}

@BuildStep(onlyIf = IsLocalDevelopment.class)
AdditionalBeanBuildItem additionalBeans() {
return AdditionalBeanBuildItem.builder()
.addBeanClasses(
ManagementLifecycleListener.class,
InMemoryWorkflowInstanceStore.class)
.setUnremovable()
.build();
}

@BuildStep(onlyIf = IsLocalDevelopment.class)
@Record(ExecutionTime.RUNTIME_INIT)
void produceApplicationBuilder(InjectManagementListenerRecorder recorder, WorkflowApplicationBuilderBuildItem builderItem) {
recorder.addManagementLifecycleListener(builderItem.builder());
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package io.quarkiverse.flow.deployment.test.devui;

import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function;

import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkiverse.flow.Flow;
import io.serverlessworkflow.api.types.Workflow;
import io.serverlessworkflow.fluent.spec.WorkflowBuilder;
import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder;

@ApplicationScoped
public class DevUIWorkflow extends Flow {

@Override
public Workflow descriptor() {
return WorkflowBuilder.workflow("helloQuarkus")
return FuncWorkflowBuilder.workflow("helloQuarkus")
.tasks(t -> t.set("taskHello", """
{ "message": "helloWorld" }
"""))
"""),
function("aliceFn", person -> Map.of("name", "Alice"), Map.class),
function("messageFn", person -> Map.of("message", "Message from " + person.get("name") + " to me!"),
Map.class))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package io.quarkiverse.flow.deployment.test.devui;

import java.util.Map;

import org.assertj.core.api.Assertions;
import org.assertj.core.api.SoftAssertions;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.fasterxml.jackson.databind.JsonNode;

import io.quarkus.devui.tests.DevUIJsonRPCTest;
import io.quarkus.test.QuarkusDevModeTest;
import io.restassured.RestAssured;
import io.vertx.core.json.JsonArray;

public class LifecycleManagementDevUIJsonRPCTest extends DevUIJsonRPCTest {

@RegisterExtension
static final QuarkusDevModeTest devMode = new QuarkusDevModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(GreetingResource.class, DevUIWorkflow.class));

public LifecycleManagementDevUIJsonRPCTest() {
super("quarkus-flow");
}

@Test
void should_not_get_due_to_pagination_size_as_zero() throws Exception {

executeDevUiWorkflowSomeTimes(1);

JsonNode root = super.executeJsonRPCMethod("listAllWorkflowInstances", Map.of(
"page", 0,
"size", 0,
"sort", "START_TIME_ASC"));

JsonArray array = new JsonArray(root.toString());

Assertions.assertThat(array)
.as("should not have items because the page is 0 and the size is 0")
.isEmpty();
}

@Test
void paginate_options_should_work_as_expected() throws Exception {

executeDevUiWorkflowSomeTimes(5);

SoftAssertions softly = new SoftAssertions();

JsonNode sizeJson = super.executeJsonRPCMethod("listAllWorkflowInstances", Map.of(
"page", 0,
"size", 3,
"sort", "START_TIME_ASC"));

JsonArray array = new JsonArray(sizeJson.toString());

softly.assertThat(array.size()).isEqualTo(3)
.as("should have only three workflow instances because we are in the page 0 and the size is 5");

JsonNode pageJson = super.executeJsonRPCMethod("listAllWorkflowInstances", Map.of(
"page", 1,
"size", 10,
"sort", "START_TIME_ASC"));

JsonArray pageArray = new JsonArray(pageJson.toString());

softly.assertThat(pageArray)
.as("should not have workflow instances because the page is 1 (there is no item in page 1 with size 10")
.isEmpty();

softly.assertAll();
}

@Test
void should_get_by_status() throws Exception {
executeDevUiWorkflowSomeTimes(1);

JsonNode root = this.executeJsonRPCMethod("findByStatus", Map.of("status", "COMPLETED"));

SoftAssertions softly = new SoftAssertions();

for (JsonNode jsonNode : root) {
softly.assertThat(jsonNode.get("status").asText()).isEqualTo("COMPLETED");
}

JsonNode faulted = this.executeJsonRPCMethod("findByStatus", Map.of("status", "FAULTED", "page", 0, "size", 10));

softly.assertThat(faulted)
.as("should not have faulted workflows")
.isEmpty();

softly.assertAll();
}

@Test
void should_get_workflow_instance_by_id() throws Exception {

executeDevUiWorkflowSomeTimes(1);

JsonNode root = this.executeJsonRPCMethod("findByStatus", Map.of("status", "COMPLETED", "page", 0, "size", 10));
JsonNode workflowInstance = root.valueStream().findFirst().orElseThrow();

SoftAssertions softly = new SoftAssertions();

String instanceId = workflowInstance.get("instanceId").asText();
softly.assertThat(instanceId).isNotNull();
softly.assertThat(instanceId).isNotBlank();

JsonNode jsonNode = this.executeJsonRPCMethod("findByWorkflowId", Map.of(
"instanceId", instanceId));

softly.assertThat(jsonNode.get("instanceId").asText()).isEqualTo(instanceId).as(
"the instance ID must be the same value");

softly.assertAll();
}

private static void executeDevUiWorkflowSomeTimes(int times) {
for (int i = 0; i < times; i++) {
RestAssured.given()
.get("/hello")
.then()
.statusCode(200);
}
}
}
10 changes: 10 additions & 0 deletions core/runtime-dev/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,15 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading