diff --git a/src/main/java/it/cnr/isti/workflow/manager/controllers/ExecutionsController.java b/src/main/java/it/cnr/isti/workflow/manager/controllers/ExecutionsController.java index 72226e5..02cf697 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/controllers/ExecutionsController.java +++ b/src/main/java/it/cnr/isti/workflow/manager/controllers/ExecutionsController.java @@ -101,7 +101,7 @@ public class ExecutionsController { FlowEntity flow = flowRepository.findById(flowId) .orElseThrow(() -> new IllegalArgumentException("Flow with id " + flowId + " not found")); try{ - ExecutionObject eo = executionService.createExecution(flow.getFlow()); + ExecutionObject eo = executionService.createExecution(flow.getName(), flow.getFlow()); return eo; } catch (Throwable e) { logger.error("Error creating execution for flow {}", flowId, e); diff --git a/src/main/java/it/cnr/isti/workflow/manager/controllers/FlowController.java b/src/main/java/it/cnr/isti/workflow/manager/controllers/FlowController.java index d410fc5..d2b4bb8 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/controllers/FlowController.java +++ b/src/main/java/it/cnr/isti/workflow/manager/controllers/FlowController.java @@ -5,17 +5,18 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.eclipse.microprofile.openapi.annotations.Operation; +import jakarta.validation.Valid; import it.cnr.isti.workflow.manager.auth.repo.LoginEntity; import it.cnr.isti.workflow.manager.flows.FlowService; -import it.cnr.isti.workflow.manager.flows.model.Flow; -import it.cnr.isti.workflow.manager.flows.repo.FlowEntity; -import org.springframework.web.bind.annotation.GetMapping; +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowView; @RestController @@ -27,7 +28,7 @@ public class FlowController { @GetMapping("") @Operation(summary = "Get all flows", description = "Returns the list of all available workflow definitions.") - public List getAllFlows() { + public List getAllFlows() { return flowService.getAllFlows(); } @@ -35,9 +36,10 @@ public class FlowController { @PostMapping @Operation(summary = "Create flow", description = "Creates a new flow owned by the authenticated user.") - public ResponseEntity createFlow(@RequestBody Flow flow, @AuthenticationPrincipal + public ResponseEntity createFlow(@RequestBody @Valid FlowCreateRequest flow, + @AuthenticationPrincipal LoginEntity userDetails) { - FlowEntity createdFlow = flowService.createFlow(userDetails.getUsername(), flow); + FlowView createdFlow = flowService.createFlow(userDetails.getUsername(), flow); return ResponseEntity.ok(createdFlow); } diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionObject.java b/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionObject.java index ab3d418..9aa5de1 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionObject.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionObject.java @@ -15,7 +15,7 @@ import it.cnr.isti.workflow.manager.executions.steps.Input; import it.cnr.isti.workflow.manager.executions.steps.Output; import it.cnr.isti.workflow.manager.executions.steps.Step; import it.cnr.isti.workflow.manager.flows.model.Connection; -import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowData; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -36,7 +36,7 @@ public class ExecutionObject { ExecutorService executorService; @Builder - public ExecutionObject(String executionName, Flow flow) { + public ExecutionObject(String executionName, FlowData flow) { this.name = executionName; List> steps = getStepsFromFlow(flow); @@ -47,11 +47,11 @@ public class ExecutionObject { } - List> getStepsFromFlow(Flow flow) { + List> getStepsFromFlow(FlowData flow) { List> steps = new ArrayList<>(); flow.getBlocks().stream().filter(b -> BlockExecutors.get(b.getType()) == null).findAny().ifPresent(b -> { throw new IllegalStateException("No executor found for block type " + b.getType().getName() - + ". Cannot create execution for flow " + flow.getName()); + + ". Cannot create execution"); }); flow.getBlocks().forEach(block -> steps.add(new Step<>(block))); for (Connection connection: flow.getConnections()){ @@ -96,4 +96,4 @@ public class ExecutionObject { + " is not in READY status (CURRENT STATUS is " + this.getContext().getStatus() + ")"); } -} \ No newline at end of file +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionsService.java b/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionsService.java index 235a1a0..2f9852c 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionsService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/executions/ExecutionsService.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; import org.springframework.stereotype.Service; import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowData; @Service public class ExecutionsService { @@ -12,15 +13,23 @@ public class ExecutionsService { private static Map executions = new HashMap<>(); - public ExecutionObject createExecution(Flow flow) { + public ExecutionObject createExecution(String executionName, FlowData flow) { ExecutionObject execObject = ExecutionObject.builder() - .executionName(flow.getName()) + .executionName(executionName) .flow(flow) .build(); executions.put(execObject.getId(), execObject); return execObject; } + public ExecutionObject createExecution(Flow flow) { + FlowData flowData = FlowData.builder() + .blocks(flow.getBlocks()) + .connections(flow.getConnections()) + .build(); + return createExecution(flow.getName(), flowData); + } + public ExecutionObject getExecution(String id) { ExecutionObject toReturn = executions.get(id); if (toReturn == null) @@ -59,4 +68,4 @@ public class ExecutionsService { } -} \ No newline at end of file +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/FlowConverter.java b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowConverter.java index 7b3c3d0..5c129da 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/flows/FlowConverter.java +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowConverter.java @@ -2,36 +2,36 @@ package it.cnr.isti.workflow.manager.flows; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowData; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; @Converter(autoApply = false) -public class FlowConverter implements AttributeConverter { +public class FlowConverter implements AttributeConverter { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override - public String convertToDatabaseColumn(Flow flow) { - if (flow == null) { + public String convertToDatabaseColumn(FlowData flowData) { + if (flowData == null) { return null; } try { - return objectMapper.writeValueAsString(flow); + return objectMapper.writeValueAsString(flowData); } catch (JsonProcessingException e) { - throw new IllegalArgumentException("Errore nella serializzazione di Flow in JSON", e); + throw new IllegalArgumentException("Errore nella serializzazione di FlowData in JSON", e); } } @Override - public Flow convertToEntityAttribute(String dbData) { + public FlowData convertToEntityAttribute(String dbData) { if (dbData == null || dbData.isBlank()) { return null; } try { - return objectMapper.readValue(dbData, Flow.class); + return objectMapper.readValue(dbData, FlowData.class); } catch (Exception e) { - throw new IllegalArgumentException("Errore nella deserializzazione di JSON in Flow", e); + throw new IllegalArgumentException("Errore nella deserializzazione di JSON in FlowData", e); } } } \ No newline at end of file diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/FlowMapper.java b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowMapper.java new file mode 100644 index 0000000..1d29f50 --- /dev/null +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowMapper.java @@ -0,0 +1,38 @@ +package it.cnr.isti.workflow.manager.flows; + +import java.time.LocalDateTime; + +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowView; +import it.cnr.isti.workflow.manager.flows.repo.FlowEntity; + +public final class FlowMapper { + + private FlowMapper() { + } + + public static FlowEntity toNewEntity(String owner, FlowCreateRequest request) { + LocalDateTime now = LocalDateTime.now(); + FlowEntity entity = new FlowEntity(); + entity.setName(request.name()); + entity.setDescription(request.description()); + entity.setOwner(owner); + entity.setCreatedAt(now); + entity.setLastUpdateAt(now); + entity.setFlow(request.flow()); + return entity; + } + + public static FlowView toView(FlowEntity entity) { + return new FlowView( + entity.getId(), + entity.getName(), + entity.getDescription(), + entity.getCreatedAt(), + entity.getLastUpdateAt(), + entity.getOwner(), + entity.isPublished(), + entity.isFinalized(), + entity.getFlow()); + } +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/FlowService.java b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowService.java index 586e29a..dbc1647 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/flows/FlowService.java +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/FlowService.java @@ -1,12 +1,12 @@ package it.cnr.isti.workflow.manager.flows; -import java.time.LocalDateTime; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowView; import it.cnr.isti.workflow.manager.flows.repo.FlowEntity; import it.cnr.isti.workflow.manager.flows.repo.FlowRepository; @@ -16,18 +16,13 @@ public class FlowService { @Autowired FlowRepository flowRepository; - public FlowEntity createFlow(String owner, Flow flow) { - FlowEntity flowEntity = new FlowEntity(); - flowEntity.setName(flow.getName()); - LocalDateTime now = LocalDateTime.now(); - flowEntity.setCreatedAt(now); - flowEntity.setLastUpdateAt(now); - flowEntity.setFlow(flow); - flowEntity.setOwner(owner); - return flowRepository.save(flowEntity); + public FlowView createFlow(String owner, FlowCreateRequest request) { + FlowEntity flowEntity = FlowMapper.toNewEntity(owner, request); + FlowEntity savedEntity = flowRepository.save(flowEntity); + return FlowMapper.toView(savedEntity); } - public List getAllFlows() { - return flowRepository.findAll().stream().map(FlowEntity::getFlow).toList(); + public List getAllFlows() { + return flowRepository.findAll().stream().map(FlowMapper::toView).toList(); } } diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/model/Flow.java b/src/main/java/it/cnr/isti/workflow/manager/flows/model/Flow.java index e285ae7..cef6d64 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/flows/model/Flow.java +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/model/Flow.java @@ -28,5 +28,4 @@ public class Flow { @Singular List connections; - } diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowCreateRequest.java b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowCreateRequest.java new file mode 100644 index 0000000..b8ad66c --- /dev/null +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowCreateRequest.java @@ -0,0 +1,10 @@ +package it.cnr.isti.workflow.manager.flows.model; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record FlowCreateRequest( + @NotBlank String name, + String description, + @NotNull FlowData flow) { +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowData.java b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowData.java new file mode 100644 index 0000000..bfb4294 --- /dev/null +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowData.java @@ -0,0 +1,26 @@ +package it.cnr.isti.workflow.manager.flows.model; + +import java.util.List; + +import it.cnr.isti.workflow.manager.blocks.Block; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Singular; + +@Data +@Builder +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@AllArgsConstructor +public class FlowData { + + @Singular + List> blocks; + + @Singular + List connections; + +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowView.java b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowView.java new file mode 100644 index 0000000..5078f37 --- /dev/null +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/model/FlowView.java @@ -0,0 +1,15 @@ +package it.cnr.isti.workflow.manager.flows.model; + +import java.time.LocalDateTime; + +public record FlowView( + String id, + String name, + String description, + LocalDateTime createdAt, + LocalDateTime lastUpdateAt, + String owner, + boolean published, + boolean finalized, + FlowData flow) { +} diff --git a/src/main/java/it/cnr/isti/workflow/manager/flows/repo/FlowEntity.java b/src/main/java/it/cnr/isti/workflow/manager/flows/repo/FlowEntity.java index bff3f78..4230b78 100644 --- a/src/main/java/it/cnr/isti/workflow/manager/flows/repo/FlowEntity.java +++ b/src/main/java/it/cnr/isti/workflow/manager/flows/repo/FlowEntity.java @@ -3,7 +3,7 @@ package it.cnr.isti.workflow.manager.flows.repo; import java.time.LocalDateTime; import it.cnr.isti.workflow.manager.flows.FlowConverter; -import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowData; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; @@ -54,5 +54,5 @@ public class FlowEntity { @Lob @Column(name = "flow_data", columnDefinition = "TEXT") @Convert(converter = FlowConverter.class) - private Flow flow; + private FlowData flow; } diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java index 5735d42..023a7f5 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/ExecutionControllerTest.java @@ -19,7 +19,9 @@ import it.cnr.isti.workflow.manager.executions.ExecutionObject; import it.cnr.isti.workflow.manager.executions.ExecutionStatus; import it.cnr.isti.workflow.manager.flows.model.Connection; import it.cnr.isti.workflow.manager.flows.model.Flow; -import it.cnr.isti.workflow.manager.flows.repo.FlowEntity; +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowData; +import it.cnr.isti.workflow.manager.flows.model.FlowView; import it.cnr.isti.workflow.manager.llms.LLMDescriptor; @SpringBootTest @@ -72,8 +74,12 @@ public class ExecutionControllerTest { .connection(connection) .build(); - ResponseEntity createdFlow = flowController.createFlow(flow, new LoginEntity("testuser", "testpassword")); - ExecutionObject executionObject = executionsController.create(createdFlow.getBody().getId()); + FlowCreateRequest request = new FlowCreateRequest( + flow.getName(), + flow.getDescription(), + FlowData.builder().blocks(flow.getBlocks()).connections(flow.getConnections()).build()); + ResponseEntity createdFlow = flowController.createFlow(request, new LoginEntity("testuser", "testpassword")); + ExecutionObject executionObject = executionsController.create(createdFlow.getBody().id()); assert executionObject != null; assert executionObject.getId() != null; diff --git a/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java b/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java new file mode 100644 index 0000000..9ff3ed9 --- /dev/null +++ b/src/test/java/it/cnr/isti/workflow/manager/controllers/FlowControllerTest.java @@ -0,0 +1,84 @@ +package it.cnr.isti.workflow.manager.controllers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.TestPropertySource; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import it.cnr.isti.workflow.manager.app.ObjectMapperHolder; +import it.cnr.isti.workflow.manager.auth.repo.LoginEntity; +import it.cnr.isti.workflow.manager.flows.FlowTestCreator; +import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowData; +import it.cnr.isti.workflow.manager.flows.model.FlowView; +import it.cnr.isti.workflow.manager.llms.LLMDescriptor; + +@SpringBootTest +@TestPropertySource(locations = "classpath:test.properties") +public class FlowControllerTest { + + @Autowired + private FlowController flowController; + + @Autowired + private FlowTestCreator flowTestCreator; + + @Test + public void createAndGetFlow() { + LLMDescriptor llmDescriptor = LLMDescriptor.builder() + .provider("testProvider") + .model("testModel") + .build(); + + Flow flow = flowTestCreator.createFlowWithConnection(llmDescriptor); + FlowCreateRequest request = new FlowCreateRequest( + flow.getName(), + flow.getDescription(), + FlowData.builder() + .blocks(flow.getBlocks()) + .connections(flow.getConnections()) + .build()); + + ResponseEntity createResponse = flowController.createFlow( + request, + new LoginEntity("testuser", "testpassword")); + + assertTrue(createResponse.getStatusCode().is2xxSuccessful()); + assertNotNull(createResponse.getBody()); + FlowView created = createResponse.getBody(); + assertNotNull(created.id()); + + List flows = flowController.getAllFlows(); + assertNotNull(flows); + + FlowView retrieved = flows.stream() + .filter(f -> created.id().equals(f.id())) + .findFirst() + .orElse(null); + + try { + System.out.println(ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(retrieved)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + assertNotNull(retrieved); + assertEquals(created.id(), retrieved.id()); + assertEquals("testuser", retrieved.owner()); + assertEquals(flow.getName(), retrieved.name()); + assertEquals(flow.getDescription(), retrieved.description()); + assertNotNull(retrieved.flow()); + assertEquals(flow.getBlocks().size(), retrieved.flow().getBlocks().size()); + assertEquals(flow.getConnections().size(), retrieved.flow().getConnections().size()); + } +} diff --git a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java index f09c273..bf413f0 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java +++ b/src/test/java/it/cnr/isti/workflow/manager/executions/ExecutionWithContainer.java @@ -159,4 +159,54 @@ public class ExecutionWithContainer { } } + + @Test + public void getInteractiveFlowWithStop() { + Flow flow = flowTestCreator.createFlowWithInteraction(llmBrick); + assertNotNull(flow); + ExecutionObject execObject = executionsService.createExecution(flow); + assertNotNull(execObject); + assertEquals(ExecutionStatus.CREATED, execObject.getContext().getStatus()); + try { + logger.info("Execution object in CREATED State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + for (Step s : execObject.getContext().getSteps().values()) { + if (s.getInputs().stream().anyMatch(i -> i.getDescriptor().getName().equals("name") && !i.isRegistered())) { + executionsService.prepareInput(execObject.getId(), s.getId(), "name", "marie curie"); + } + } + + assertEquals(ExecutionStatus.READY, execObject.getContext().getStatus()); + + try { + logger.info("Execution object in READY State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + execObject = executionsService.startExecution(execObject.getId()); + while (execObject.getContext().getStatus() == ExecutionStatus.RUNNING) { + try { + Thread.sleep(500); + logger.debug("Execution status: " + execObject.getContext().getStatus()); + execObject = executionsService.getExecution(execObject.getId()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + assertEquals(ExecutionStatus.WAITING, execObject.getContext().getStatus()); + + try { + logger.info("Execution object in WAITING State: {}", ObjectMapperHolder.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(execObject)); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } } diff --git a/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java b/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java index 7a6c0d4..5129e2e 100644 --- a/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java +++ b/src/test/java/it/cnr/isti/workflow/manager/flows/FlowTest.java @@ -7,6 +7,8 @@ import org.springframework.test.context.TestPropertySource; import com.fasterxml.jackson.databind.ObjectMapper; import it.cnr.isti.workflow.manager.flows.model.Flow; +import it.cnr.isti.workflow.manager.flows.model.FlowCreateRequest; +import it.cnr.isti.workflow.manager.flows.model.FlowData; import it.cnr.isti.workflow.manager.llms.LLMDescriptor; @SpringBootTest @@ -27,13 +29,13 @@ public class FlowTest { @Test public void createEmptyFlow() { Flow flow = Flow.builder().name("Test Flow").description("This is a test flow").build(); - flowService.createFlow("testUser", flow ); + flowService.createFlow("testUser", toCreateRequest(flow)); } @Test public void createFlow() { Flow flow = flowTestCreator.createFlowWithConnection(llmBrick); - flowService.createFlow("testUser", flow ); + flowService.createFlow("testUser", toCreateRequest(flow)); } @Test @@ -58,5 +60,12 @@ public class FlowTest { assert(json.equals(json2)); } + private FlowCreateRequest toCreateRequest(Flow flow) { + FlowData flowData = FlowData.builder() + .blocks(flow.getBlocks()) + .connections(flow.getConnections()) + .build(); + return new FlowCreateRequest(flow.getName(), flow.getDescription(), flowData); + } }