From 86990874599bcc5bc007017e6218dfc978770d3a Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Thu, 3 Aug 2023 11:37:15 +0200 Subject: [PATCH 1/3] Revert "[KOGITO-9614] Kogito changes for new asyncapi extension version (#3147)" This reverts commit decf232adc6ae394fc673c581541a3c53415f75a. --- .../validation/ValidationDecorator.java | 4 +- .../validation/ValidationLogDecorator.java | 2 +- kogito-build/kogito-dependencies-bom/pom.xml | 2 +- .../codegen/process/ProcessCodegen.java | 18 ++++----- .../process/ProcessParsingException.java | 5 ++- .../workflow/WorkflowCodeGenUtils.java | 39 ++++++++++++------- ...ier.java => AsyncInputStreamSupplier.java} | 6 +-- ...=> WorkflowAsyncApiSpecInputProvider.java} | 28 +++++++------ ...oadableAsyncApiGeneratorStreamCodeGen.java | 28 +++++++++++++ .../WorkflowOpenApiSpecInputProvider.java | 5 +-- .../rpc/WorkflowRPCCodeGenProvider.java | 4 +- ...generator.input.AsyncApiSpecInputProvider} | 2 +- ...t.livereload.LiveReloadableCodeGenProvider | 1 + .../pom.xml | 10 +++++ .../livereload/LiveReloadProcessorTest.java | 2 + 15 files changed, 106 insertions(+), 50 deletions(-) rename quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/{AsyncAPIInputStreamSupplier.java => AsyncInputStreamSupplier.java} (82%) rename quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/{WorkflowAsyncAPISpecInputProvider.java => WorkflowAsyncApiSpecInputProvider.java} (52%) create mode 100644 quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadableAsyncApiGeneratorStreamCodeGen.java rename quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/{io.quarkiverse.asyncapi.config.AsyncAPISpecInputProvider => io.quarkiverse.asyncapi.generator.input.AsyncApiSpecInputProvider} (75%) diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java index 60798fbf572..ee654455615 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java @@ -19,9 +19,9 @@ public abstract class ValidationDecorator { - protected final Map exceptions; + protected final Map exceptions; - protected ValidationDecorator(Map exceptions) { + protected ValidationDecorator(Map exceptions) { this.exceptions = exceptions; } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java index 8f4812028af..dddd7fdd736 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java @@ -24,7 +24,7 @@ public class ValidationLogDecorator extends ValidationDecorator { private static final Logger LOGGER = LoggerFactory.getLogger(ValidationLogDecorator.class); - public ValidationLogDecorator(Map exceptions) { + public ValidationLogDecorator(Map exceptions) { super(exceptions); } diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index 4c79cc0340b..7257ecc1b3c 100644 --- a/kogito-build/kogito-dependencies-bom/pom.xml +++ b/kogito-build/kogito-dependencies-bom/pom.xml @@ -30,7 +30,7 @@ 1.0.0-preview.20220705 1.1.0 1.3.8 - 0.0.5 + 0.0.3 1.1.5 0.0.8 1.5.2 diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java index a433dfae7ad..946edbac927 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java @@ -106,7 +106,7 @@ public class ProcessCodegen extends AbstractGenerator { public static ProcessCodegen ofCollectedResources(KogitoBuildContext context, Collection resources) { Map processSVGMap = new HashMap<>(); - Map processesErrors = new HashMap<>(); + Map processesErrors = new HashMap<>(); boolean useSvgAddon = context.getAddonsConfig().useProcessSVG(); final List> processes = resources.stream() .map(CollectedResource::resource) @@ -123,13 +123,13 @@ public static ProcessCodegen ofCollectedResources(KogitoBuildContext context, Co GeneratedInfo generatedInfo = parseWorkflowFile(resource, WorkflowFormat.fromFileName(resource.getSourcePath()), context); notifySourceFileCodegenBindListeners(context, resource, Collections.singletonList(generatedInfo.info())); return Stream.of(addResource(generatedInfo, resource)); + } else { + return Stream.empty(); } - } catch (ValidationException e) { + } catch (ValidationException | ProcessParsingException e) { processesErrors.put(resource.getSourcePath(), e); - } catch (ProcessParsingException e) { - processesErrors.put(resource.getSourcePath(), e.getCause()); + return Stream.empty(); } - return Stream.empty(); }) //Validate parsed processes .map(processInfo -> validate(processInfo, processesErrors)) @@ -154,7 +154,7 @@ private static void notifySourceFileCodegenBindListeners(KogitoBuildContext cont .ifPresent(notifier -> processes.forEach(p -> notifier.notify(new SourceFileCodegenBindEvent(p.getId(), resource.getSourcePath())))); } - private static void handleValidation(KogitoBuildContext context, Map processesErrors) { + private static void handleValidation(KogitoBuildContext context, Map processesErrors) { if (!processesErrors.isEmpty()) { ValidationLogDecorator decorator = new ValidationLogDecorator(processesErrors); decorator.decorate(); @@ -165,7 +165,7 @@ private static void handleValidation(KogitoBuildContext context, Map validate(GeneratedInfo processInfo, Map processesErrors) { + private static GeneratedInfo validate(GeneratedInfo processInfo, Map processesErrors) { Process process = processInfo.info(); try { ProcessValidatorRegistry.getInstance().getValidator(process, process.getResource()).validate(process); @@ -216,7 +216,7 @@ protected static GeneratedInfo parseWorkflowFile(Resource try (Reader reader = r.getReader()) { return ServerlessWorkflowParser.of(reader, format, context).getProcessInfo(); } catch (IOException | RuntimeException e) { - throw new ProcessParsingException(e); + throw new ProcessParsingException("Could not parse file " + r.getSourcePath(), e); } } @@ -227,7 +227,7 @@ protected static Collection parseProcessFile(Resource r) { Thread.currentThread().getContextClassLoader()); return xmlReader.read(reader); } catch (SAXException | IOException e) { - throw new ProcessParsingException(e); + throw new ProcessParsingException("Could not parse file " + r.getSourcePath(), e); } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java index 537db0ce99d..9df885d01b6 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java @@ -16,9 +16,12 @@ package org.kie.kogito.codegen.process; public class ProcessParsingException extends RuntimeException { - private static final long serialVersionUID = 1L; public ProcessParsingException(Throwable cause) { super(cause); } + + public ProcessParsingException(String s, Throwable e) { + super(s, e); + } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java index 4419cb7a659..36f0955dbea 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.Reader; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; @@ -27,6 +28,7 @@ import org.drools.codegen.common.GeneratedFile; import org.drools.codegen.common.GeneratedFileType; +import org.eclipse.microprofile.config.ConfigProvider; import org.kie.kogito.codegen.api.context.KogitoBuildContext; import org.kie.kogito.internal.SupportedExtensions; import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory; @@ -40,9 +42,12 @@ import com.github.javaparser.ast.CompilationUnit; +import io.quarkus.deployment.CodeGenContext; import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.functions.FunctionDefinition; +import static org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.FAIL_ON_ERROR_PROPERTY; + public class WorkflowCodeGenUtils { private static final Logger logger = LoggerFactory.getLogger(WorkflowCodeGenUtils.class); @@ -51,8 +56,12 @@ public class WorkflowCodeGenUtils { private WorkflowCodeGenUtils() { } - public static Stream operationResources(Stream files, Predicate predicate, Optional operationIdProp) { - return getWorkflows(files).flatMap(w -> processFunction(w, predicate, WorkflowOperationIdFactoryProvider.getFactory(operationIdProp))); + private static WorkflowOperationIdFactory operationIdFactory(CodeGenContext context) { + return WorkflowOperationIdFactoryProvider.getFactory(context.config().getOptionalValue(WorkflowOperationIdFactoryProvider.PROPERTY_NAME, String.class)); + } + + public static Stream operationResources(Stream files, Predicate predicate, CodeGenContext context) { + return getWorkflows(files).flatMap(w -> processFunction(w, predicate, operationIdFactory(context))); } public static Stream getWorkflows(Stream files) { @@ -87,16 +96,20 @@ private static WorkflowOperationResource getResource(Workflow workflow, Function } private static Optional getWorkflow(Path path) { - if (SupportedExtensions.getSWFExtensions().stream().anyMatch(ext -> path.toString().endsWith(ext))) { - return workflowCache.computeIfAbsent(path, p -> { - try (Reader r = Files.newBufferedReader(p)) { - return Optional.of(ServerlessWorkflowUtils.getWorkflow(r, WorkflowFormat.fromFileName(p.getFileName()))); - } catch (IOException ex) { - logger.info("Error reading workflow file {}. Ignoring exception {}", p, ex); - return Optional. empty(); - } - }); - } - return Optional.empty(); + return workflowCache.computeIfAbsent(path, p -> SupportedExtensions.getSWFExtensions() + .stream() + .filter(e -> p.getFileName().toString().endsWith(e)) + .map(e -> { + try (Reader r = Files.newBufferedReader(p)) { + return Optional.of(ServerlessWorkflowUtils.getWorkflow(r, WorkflowFormat.fromFileName(p.getFileName()))); + } catch (IOException ex) { + if (ConfigProvider.getConfig().getOptionalValue(FAIL_ON_ERROR_PROPERTY, Boolean.class).orElse(true)) { + throw new UncheckedIOException(ex); + } else { + logger.error("Error reading workflow file {}", p, ex); + return Optional. empty(); + } + } + }).flatMap(Optional::stream).findFirst()); } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIInputStreamSupplier.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncInputStreamSupplier.java similarity index 82% rename from quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIInputStreamSupplier.java rename to quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncInputStreamSupplier.java index b1e21b1e7b1..5eb190eb1ad 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIInputStreamSupplier.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncInputStreamSupplier.java @@ -19,13 +19,13 @@ import org.kie.kogito.quarkus.serverless.workflow.WorkflowOperationResource; -import io.quarkiverse.asyncapi.config.InputStreamSupplier; +import io.quarkiverse.asyncapi.generator.input.InputStreamSupplier; -class AsyncAPIInputStreamSupplier implements InputStreamSupplier { +class AsyncInputStreamSupplier implements InputStreamSupplier { private final WorkflowOperationResource resource; - public AsyncAPIInputStreamSupplier(WorkflowOperationResource resource) { + public AsyncInputStreamSupplier(WorkflowOperationResource resource) { this.resource = resource; } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncAPISpecInputProvider.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncApiSpecInputProvider.java similarity index 52% rename from quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncAPISpecInputProvider.java rename to quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncApiSpecInputProvider.java index 20eb18918a6..2add1560b51 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncAPISpecInputProvider.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/WorkflowAsyncApiSpecInputProvider.java @@ -18,27 +18,31 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import org.kie.kogito.quarkus.serverless.workflow.WorkflowCodeGenUtils; -import org.kie.kogito.serverless.workflow.operationid.WorkflowOperationIdFactoryProvider; -import io.quarkiverse.asyncapi.config.AsyncAPISpecInput; -import io.quarkiverse.asyncapi.config.AsyncAPISpecInputProvider; +import io.quarkiverse.asyncapi.generator.input.AsyncAPISpecInput; +import io.quarkiverse.asyncapi.generator.input.AsyncApiSpecInputProvider; +import io.quarkus.deployment.CodeGenContext; import io.serverlessworkflow.api.functions.FunctionDefinition.Type; -import io.smallrye.config.ConfigSourceContext; -public class WorkflowAsyncAPISpecInputProvider implements AsyncAPISpecInputProvider { +public class WorkflowAsyncApiSpecInputProvider implements AsyncApiSpecInputProvider { + + private static final String KOGITO_PACKAGE_PREFIX = "org.kie.kogito.asyncAPI"; @Override - public AsyncAPISpecInput read(ConfigSourceContext context) throws IOException { - try (Stream workflowFiles = Files.walk(Path.of(System.getProperty("user.dir")))) { - return new AsyncAPISpecInput(WorkflowCodeGenUtils - .operationResources(workflowFiles, f -> f.getType() == Type.ASYNCAPI, - Optional.ofNullable(context.getValue(WorkflowOperationIdFactoryProvider.PROPERTY_NAME).getValue())) - .collect(Collectors.toMap(resource -> resource.getOperationId().getFileName(), AsyncAPIInputStreamSupplier::new, (key1, key2) -> key1))); + public AsyncAPISpecInput read(CodeGenContext context) { + Path inputDir = context.inputDir(); + while (!Files.exists(inputDir)) { + inputDir = inputDir.getParent(); + } + try (Stream workflowFiles = Files.walk(inputDir)) { + return new AsyncAPISpecInput(WorkflowCodeGenUtils.operationResources(workflowFiles, f -> f.getType() == Type.ASYNCAPI, context) + .collect(Collectors.toMap(resource -> resource.getOperationId().getFileName(), AsyncInputStreamSupplier::new, (key1, key2) -> key1)), KOGITO_PACKAGE_PREFIX); + } catch (IOException io) { + throw new IllegalStateException(io); } } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadableAsyncApiGeneratorStreamCodeGen.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadableAsyncApiGeneratorStreamCodeGen.java new file mode 100644 index 00000000000..b3c76ffe20d --- /dev/null +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadableAsyncApiGeneratorStreamCodeGen.java @@ -0,0 +1,28 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed 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.quarkus.serverless.workflow.deployment.livereload; + +import io.quarkiverse.asyncapi.generator.input.AsyncApiGeneratorStreamCodeGen; + +/** + * Wrapper for {@link AsyncApiGeneratorStreamCodeGen} that implements the {@link LiveReloadableCodeGenProvider} Service Provider Interface. + */ +public class LiveReloadableAsyncApiGeneratorStreamCodeGen extends LiveReloadableCodeGenProviderBase { + + public LiveReloadableAsyncApiGeneratorStreamCodeGen() { + super(new AsyncApiGeneratorStreamCodeGen()); + } +} diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/openapi/WorkflowOpenApiSpecInputProvider.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/openapi/WorkflowOpenApiSpecInputProvider.java index 68532057d95..c703de138dc 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/openapi/WorkflowOpenApiSpecInputProvider.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/openapi/WorkflowOpenApiSpecInputProvider.java @@ -24,7 +24,6 @@ import org.kie.kogito.quarkus.serverless.workflow.WorkflowCodeGenUtils; import org.kie.kogito.quarkus.serverless.workflow.WorkflowOperationResource; -import org.kie.kogito.serverless.workflow.operationid.WorkflowOperationIdFactoryProvider; import org.kie.kogito.serverless.workflow.utils.OpenAPIWorkflowUtils; import io.quarkiverse.openapi.generator.deployment.codegen.OpenApiSpecInputProvider; @@ -42,9 +41,7 @@ public List read(CodeGenContext context) { inputDir = inputDir.getParent(); } try (Stream openApiFilesPaths = Files.walk(inputDir)) { - return WorkflowCodeGenUtils - .operationResources(openApiFilesPaths, OpenAPIWorkflowUtils::isOpenApiOperation, context.config().getOptionalValue(WorkflowOperationIdFactoryProvider.PROPERTY_NAME, String.class)) - .map(this::getSpecInput).collect(Collectors.toList()); + return WorkflowCodeGenUtils.operationResources(openApiFilesPaths, OpenAPIWorkflowUtils::isOpenApiOperation, context).map(this::getSpecInput).collect(Collectors.toList()); } catch (IOException io) { throw new IllegalStateException(io); } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/rpc/WorkflowRPCCodeGenProvider.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/rpc/WorkflowRPCCodeGenProvider.java index fa7abca73af..dfe9e4898dc 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/rpc/WorkflowRPCCodeGenProvider.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/rpc/WorkflowRPCCodeGenProvider.java @@ -31,7 +31,6 @@ import org.kie.kogito.serverless.workflow.io.FileContentLoader; import org.kie.kogito.serverless.workflow.io.URIContentLoader; import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory; -import org.kie.kogito.serverless.workflow.operationid.WorkflowOperationIdFactoryProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,8 +65,7 @@ public boolean trigger(CodeGenContext context) throws CodeGenException { Path outputPath = context.workDir().resolve("proto_temp"); Files.createDirectories(outputPath); Collection protoFiles = - WorkflowCodeGenUtils.operationResources(rpcFilePaths, this::isRPC, context.config().getOptionalValue(WorkflowOperationIdFactoryProvider.PROPERTY_NAME, String.class)) - .map(r -> getPath(r, outputPath)).filter(Optional::isPresent).map(Optional::get) + WorkflowCodeGenUtils.operationResources(rpcFilePaths, this::isRPC, context).map(r -> getPath(r, outputPath)).filter(Optional::isPresent).map(Optional::get) .collect(Collectors.toList()); logger.debug("Collected proto paths are {}", protoFiles); if (protoFiles.isEmpty()) { diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.config.AsyncAPISpecInputProvider b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.generator.input.AsyncApiSpecInputProvider similarity index 75% rename from quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.config.AsyncAPISpecInputProvider rename to quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.generator.input.AsyncApiSpecInputProvider index 8fd5e949c9b..45cdf4ba110 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.config.AsyncAPISpecInputProvider +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/io.quarkiverse.asyncapi.generator.input.AsyncApiSpecInputProvider @@ -1 +1 @@ -org.kie.kogito.quarkus.serverless.workflow.asyncapi.WorkflowAsyncAPISpecInputProvider \ No newline at end of file +org.kie.kogito.quarkus.serverless.workflow.asyncapi.WorkflowAsyncApiSpecInputProvider \ No newline at end of file diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableCodeGenProvider b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableCodeGenProvider index 3287cfdc468..6bf1e19518e 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableCodeGenProvider +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/resources/META-INF/services/org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableCodeGenProvider @@ -1,2 +1,3 @@ +org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableAsyncApiGeneratorStreamCodeGen org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableOpenApiGeneratorStreamCodeGen org.kie.kogito.quarkus.serverless.workflow.deployment.livereload.LiveReloadableWorkflowRPCCodeGenProvider \ No newline at end of file diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml index 9d7ff074e20..8c0fe4812e9 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml @@ -43,15 +43,25 @@ io.grpc grpc-netty-shaded + ${version.io.grpc} runtime io.grpc grpc-protobuf + ${version.io.grpc} io.grpc grpc-stub + ${version.io.grpc} + + + + org.apache.tomcat + annotations-api + 6.0.53 + provided diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java index a9909433baf..7d8a4793aa3 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java @@ -28,6 +28,7 @@ import org.jboss.shrinkwrap.api.asset.StringAsset; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.kie.kogito.test.utils.SocketUtils; @@ -162,6 +163,7 @@ void testGrpc() throws InterruptedException, IOException { } @Test + @Disabled("Disabled until https://issues.redhat.com/browse/KOGITO-9614 is resolved") void testAsyncApi() throws IOException { given() .contentType(ContentType.JSON) From 9240a8a6ad72d9dc52dca0a5436cd53a7f7d0941 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 4 Aug 2023 22:12:14 +0200 Subject: [PATCH 2/3] [KOGITO-9614] Async api and reload --- .../validation/ValidationDecorator.java | 4 +- .../validation/ValidationLogDecorator.java | 2 +- kogito-build/kogito-dependencies-bom/pom.xml | 2 +- .../codegen/process/ProcessCodegen.java | 20 +++---- .../process/ProcessParsingException.java | 6 +- .../deployment/ChannelMappingStrategy.java | 19 +++---- .../LiveReloadExecutionBuildItem.java | 12 ++++ .../workflow/WorkflowCodeGenUtils.java | 30 ++++------ .../workflow/asyncapi/AsyncAPIProcessor.java | 16 +++--- .../livereload/LiveReloadProcessor.java | 55 ++++++++++++++----- .../pom.xml | 11 ---- .../livereload/LiveReloadProcessorTest.java | 2 - .../config/LiveReloadConfigBuilder.java | 27 +++++++++ 13 files changed, 125 insertions(+), 81 deletions(-) create mode 100644 quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/quarkus/serverless/workflow/config/LiveReloadConfigBuilder.java diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java index ee654455615..60798fbf572 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationDecorator.java @@ -19,9 +19,9 @@ public abstract class ValidationDecorator { - protected final Map exceptions; + protected final Map exceptions; - protected ValidationDecorator(Map exceptions) { + protected ValidationDecorator(Map exceptions) { this.exceptions = exceptions; } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java index dddd7fdd736..8f4812028af 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/validation/ValidationLogDecorator.java @@ -24,7 +24,7 @@ public class ValidationLogDecorator extends ValidationDecorator { private static final Logger LOGGER = LoggerFactory.getLogger(ValidationLogDecorator.class); - public ValidationLogDecorator(Map exceptions) { + public ValidationLogDecorator(Map exceptions) { super(exceptions); } diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index 7257ecc1b3c..3ea218f8492 100644 --- a/kogito-build/kogito-dependencies-bom/pom.xml +++ b/kogito-build/kogito-dependencies-bom/pom.xml @@ -30,7 +30,7 @@ 1.0.0-preview.20220705 1.1.0 1.3.8 - 0.0.3 + 0.0.6 1.1.5 0.0.8 1.5.2 diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java index 946edbac927..08961779f25 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java @@ -106,7 +106,7 @@ public class ProcessCodegen extends AbstractGenerator { public static ProcessCodegen ofCollectedResources(KogitoBuildContext context, Collection resources) { Map processSVGMap = new HashMap<>(); - Map processesErrors = new HashMap<>(); + Map processesErrors = new HashMap<>(); boolean useSvgAddon = context.getAddonsConfig().useProcessSVG(); final List> processes = resources.stream() .map(CollectedResource::resource) @@ -123,13 +123,13 @@ public static ProcessCodegen ofCollectedResources(KogitoBuildContext context, Co GeneratedInfo generatedInfo = parseWorkflowFile(resource, WorkflowFormat.fromFileName(resource.getSourcePath()), context); notifySourceFileCodegenBindListeners(context, resource, Collections.singletonList(generatedInfo.info())); return Stream.of(addResource(generatedInfo, resource)); - } else { - return Stream.empty(); } - } catch (ValidationException | ProcessParsingException e) { + } catch (ValidationException e) { processesErrors.put(resource.getSourcePath(), e); - return Stream.empty(); + } catch (ProcessParsingException e) { + processesErrors.put(resource.getSourcePath(), e.getCause()); } + return Stream.empty(); }) //Validate parsed processes .map(processInfo -> validate(processInfo, processesErrors)) @@ -154,7 +154,7 @@ private static void notifySourceFileCodegenBindListeners(KogitoBuildContext cont .ifPresent(notifier -> processes.forEach(p -> notifier.notify(new SourceFileCodegenBindEvent(p.getId(), resource.getSourcePath())))); } - private static void handleValidation(KogitoBuildContext context, Map processesErrors) { + private static void handleValidation(KogitoBuildContext context, Map processesErrors) { if (!processesErrors.isEmpty()) { ValidationLogDecorator decorator = new ValidationLogDecorator(processesErrors); decorator.decorate(); @@ -165,7 +165,7 @@ private static void handleValidation(KogitoBuildContext context, Map validate(GeneratedInfo processInfo, Map processesErrors) { + private static GeneratedInfo validate(GeneratedInfo processInfo, Map processesErrors) { Process process = processInfo.info(); try { ProcessValidatorRegistry.getInstance().getValidator(process, process.getResource()).validate(process); @@ -215,8 +215,8 @@ private static ProcessCodegen ofProcesses(KogitoBuildContext context, List parseWorkflowFile(Resource r, WorkflowFormat format, KogitoBuildContext context) { try (Reader reader = r.getReader()) { return ServerlessWorkflowParser.of(reader, format, context).getProcessInfo(); - } catch (IOException | RuntimeException e) { - throw new ProcessParsingException("Could not parse file " + r.getSourcePath(), e); + } catch (Exception e) { + throw new ProcessParsingException(e); } } @@ -227,7 +227,7 @@ protected static Collection parseProcessFile(Resource r) { Thread.currentThread().getContextClassLoader()); return xmlReader.read(reader); } catch (SAXException | IOException e) { - throw new ProcessParsingException("Could not parse file " + r.getSourcePath(), e); + throw new ProcessParsingException(e); } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java index 9df885d01b6..33ac45f8d51 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessParsingException.java @@ -17,11 +17,9 @@ public class ProcessParsingException extends RuntimeException { + private static final long serialVersionUID = 1L; + public ProcessParsingException(Throwable cause) { super(cause); } - - public ProcessParsingException(String s, Throwable e) { - super(s, e); - } } diff --git a/quarkus/addons/messaging/deployment/src/main/java/org/kie/kogito/addon/cloudevents/quarkus/deployment/ChannelMappingStrategy.java b/quarkus/addons/messaging/deployment/src/main/java/org/kie/kogito/addon/cloudevents/quarkus/deployment/ChannelMappingStrategy.java index c4e41e87494..3f9bfcc657f 100644 --- a/quarkus/addons/messaging/deployment/src/main/java/org/kie/kogito/addon/cloudevents/quarkus/deployment/ChannelMappingStrategy.java +++ b/quarkus/addons/messaging/deployment/src/main/java/org/kie/kogito/addon/cloudevents/quarkus/deployment/ChannelMappingStrategy.java @@ -50,17 +50,16 @@ private ChannelMappingStrategy() { private static final String OVERFLOW_STRATEGY_PROP = "overflow-strategy"; private static final String BUFFER_SIZE_PROP = "buffer-size"; - private static Config config = ConfigProvider.getConfig(); - public static Collection getChannelMapping() { + Config config = ConfigProvider.getConfig(); Map> inTriggers = new HashMap<>(); Map> outTriggers = new HashMap<>(); for (String property : config.getPropertyNames()) { if (property.startsWith(INCOMING_TRIGGER)) { - addTrigger(INCOMING_TRIGGER, property, inTriggers); + addTrigger(config, INCOMING_TRIGGER, property, inTriggers); } else if (property.startsWith(OUTGOING_TRIGGER)) { - addTrigger(OUTGOING_TRIGGER, property, outTriggers); + addTrigger(config, OUTGOING_TRIGGER, property, outTriggers); } } @@ -69,15 +68,15 @@ public static Collection getChannelMapping() { final String defaultOutgoingChannel = config.getOptionalValue(OUTGOING_DEFAULT_CHANNEL, String.class).orElse(KogitoEventStreams.OUTGOING); for (String property : config.getPropertyNames()) { if (property.startsWith(INCOMING_PREFIX) && property.endsWith(".connector")) { - result.add(getChannelInfo(property, INCOMING_PREFIX, true, defaultIncomingChannel, inTriggers)); + result.add(getChannelInfo(config, property, INCOMING_PREFIX, true, defaultIncomingChannel, inTriggers)); } else if (property.startsWith(OUTGOING_PREFIX) && property.endsWith(".connector")) { - result.add(getChannelInfo(property, OUTGOING_PREFIX, false, defaultOutgoingChannel, outTriggers)); + result.add(getChannelInfo(config, property, OUTGOING_PREFIX, false, defaultOutgoingChannel, outTriggers)); } } return result; } - private static void addTrigger(String prefix, String property, Map> triggers) { + private static void addTrigger(Config config, String prefix, String property, Map> triggers) { String channelName = config.getValue(property, String.class); String triggerName = property.substring(prefix.length()); triggers.computeIfAbsent(channelName, ChannelMappingStrategy::initTriggers).add(triggerName); @@ -89,15 +88,15 @@ private static Collection initTriggers(String channelName) { return result; } - private static ChannelInfo getChannelInfo(String property, String prefix, boolean isInput, String defaultChannelName, Map> triggers) { + private static ChannelInfo getChannelInfo(Config config, String property, String prefix, boolean isInput, String defaultChannelName, Map> triggers) { String name = property.substring(prefix.length(), property.lastIndexOf('.')); return new ChannelInfo(name, triggers.getOrDefault(name, Collections.singleton(name)), getClassName(config.getOptionalValue(getPropertyName(prefix, name, "value." + (isInput ? "deserializer" : "serializer")), String.class)), isInput, name.equals(defaultChannelName), config.getOptionalValue((isInput ? UNMARSHALLLER_PREFIX : MARSHALLER_PREFIX) + name, String.class), - isInput ? Optional.empty() : onOverflowInfo(name)); + isInput ? Optional.empty() : onOverflowInfo(config, name)); } - private static Optional onOverflowInfo(String name) { + private static Optional onOverflowInfo(Config config, String name) { final String namePrefix = KOGITO_EMITTER_PREFIX + name + "."; Optional strategy = config.getOptionalValue(namePrefix + OVERFLOW_STRATEGY_PROP, String.class).map(Strategy::valueOf); Optional bufferSize = config.getOptionalValue(namePrefix + BUFFER_SIZE_PROP, Long.class); diff --git a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/LiveReloadExecutionBuildItem.java b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/LiveReloadExecutionBuildItem.java index 13b0e29d705..2acd5dba91f 100644 --- a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/LiveReloadExecutionBuildItem.java +++ b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/LiveReloadExecutionBuildItem.java @@ -15,6 +15,8 @@ */ package org.kie.kogito.quarkus.common.deployment; +import java.util.Optional; + import org.jboss.jandex.IndexView; import io.quarkus.builder.item.SimpleBuildItem; @@ -22,12 +24,22 @@ public final class LiveReloadExecutionBuildItem extends SimpleBuildItem { private final IndexView indexView; + private final ClassLoader classLoader; public LiveReloadExecutionBuildItem(IndexView indexView) { + this(indexView, null); + } + + public LiveReloadExecutionBuildItem(IndexView indexView, ClassLoader classLoader) { this.indexView = indexView; + this.classLoader = classLoader; } public IndexView getIndexView() { return indexView; } + + public Optional getClassLoader() { + return Optional.ofNullable(classLoader); + } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java index 36f0955dbea..c3b9c11926a 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/WorkflowCodeGenUtils.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.io.Reader; -import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; @@ -28,7 +27,6 @@ import org.drools.codegen.common.GeneratedFile; import org.drools.codegen.common.GeneratedFileType; -import org.eclipse.microprofile.config.ConfigProvider; import org.kie.kogito.codegen.api.context.KogitoBuildContext; import org.kie.kogito.internal.SupportedExtensions; import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory; @@ -46,8 +44,6 @@ import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.functions.FunctionDefinition; -import static org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.FAIL_ON_ERROR_PROPERTY; - public class WorkflowCodeGenUtils { private static final Logger logger = LoggerFactory.getLogger(WorkflowCodeGenUtils.class); @@ -96,20 +92,16 @@ private static WorkflowOperationResource getResource(Workflow workflow, Function } private static Optional getWorkflow(Path path) { - return workflowCache.computeIfAbsent(path, p -> SupportedExtensions.getSWFExtensions() - .stream() - .filter(e -> p.getFileName().toString().endsWith(e)) - .map(e -> { - try (Reader r = Files.newBufferedReader(p)) { - return Optional.of(ServerlessWorkflowUtils.getWorkflow(r, WorkflowFormat.fromFileName(p.getFileName()))); - } catch (IOException ex) { - if (ConfigProvider.getConfig().getOptionalValue(FAIL_ON_ERROR_PROPERTY, Boolean.class).orElse(true)) { - throw new UncheckedIOException(ex); - } else { - logger.error("Error reading workflow file {}", p, ex); - return Optional. empty(); - } - } - }).flatMap(Optional::stream).findFirst()); + if (SupportedExtensions.getSWFExtensions().stream().anyMatch(ext -> path.toString().endsWith(ext))) { + return workflowCache.computeIfAbsent(path, p -> { + try (Reader r = Files.newBufferedReader(p)) { + return Optional.of(ServerlessWorkflowUtils.getWorkflow(r, WorkflowFormat.fromFileName(p.getFileName()))); + } catch (IOException ex) { + logger.info("Error reading workflow file {}. Ignoring exception {}", p, ex); + return Optional. empty(); + } + }); + } + return Optional.empty(); } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java index e59e9b3dcca..61b88efad31 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java @@ -15,21 +15,23 @@ */ package org.kie.kogito.quarkus.serverless.workflow.asyncapi; -import java.util.List; -import java.util.stream.Collectors; +import java.util.ServiceLoader; -import org.kie.kogito.quarkus.common.deployment.KogitoBuildContextAttributeBuildItem; +import org.kie.kogito.quarkus.common.deployment.KogitoAddonsPreGeneratedSourcesBuildItem; +import org.kie.kogito.quarkus.common.deployment.KogitoBuildContextBuildItem; +import org.kie.kogito.quarkus.common.deployment.LiveReloadExecutionBuildItem; import org.kie.kogito.serverless.workflow.parser.ParserContext; +import io.quarkiverse.asyncapi.config.AsyncAPISupplier; import io.quarkiverse.asyncapi.config.MapAsyncAPIRegistry; -import io.quarkiverse.asyncapi.generator.AsyncAPIBuildItem; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; public class AsyncAPIProcessor { @BuildStep - KogitoBuildContextAttributeBuildItem asyncAPIContext(List asyncAPIBuildItem) { - return new KogitoBuildContextAttributeBuildItem(ParserContext.ASYNC_CONVERTER_KEY, new AsyncAPIInfoConverter( - new MapAsyncAPIRegistry(asyncAPIBuildItem.stream().map(AsyncAPIBuildItem::getAsyncAPI).collect(Collectors.toList())))); + void asyncAPIContext(LiveReloadExecutionBuildItem reload, KogitoBuildContextBuildItem context, BuildProducer sources) throws ClassNotFoundException { + context.getKogitoBuildContext().addContextAttribute(ParserContext.ASYNC_CONVERTER_KEY, new AsyncAPIInfoConverter( + new MapAsyncAPIRegistry(ServiceLoader.load(AsyncAPISupplier.class, reload.getClassLoader().orElse(Thread.currentThread().getContextClassLoader()))))); } } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessor.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessor.java index 398cb4257e8..4940e8a2468 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessor.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessor.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.List; import java.util.ServiceLoader; +import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; @@ -40,8 +41,12 @@ import org.kie.kogito.quarkus.common.deployment.KogitoBuildContextBuildItem; import org.kie.kogito.quarkus.common.deployment.KogitoQuarkusResourceUtils; import org.kie.kogito.quarkus.common.deployment.LiveReloadExecutionBuildItem; +import org.kie.kogito.quarkus.serverless.workflow.config.LiveReloadConfigBuilder; import io.quarkus.arc.deployment.GeneratedBeanBuildItem; +import io.quarkus.bootstrap.classloading.MemoryClassPathElement; +import io.quarkus.bootstrap.classloading.PathTreeClassPathElement; +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.prebuild.CodeGenException; import io.quarkus.deployment.CodeGenContext; @@ -49,10 +54,15 @@ import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.GeneratedResourceBuildItem; import io.quarkus.deployment.builditem.LiveReloadBuildItem; +import io.quarkus.deployment.builditem.RunTimeConfigBuilderBuildItem; import io.quarkus.deployment.index.IndexingUtil; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; +import io.quarkus.paths.PathTree; +import io.quarkus.runtime.configuration.ConfigUtils; +import io.quarkus.runtime.configuration.QuarkusConfigFactory; /** * This class adds live reload support for {@link io.quarkus.deployment.CodeGenProvider} objects. @@ -71,6 +81,8 @@ public class LiveReloadProcessor { private final KogitoBuildContext kogitoBuildContext; + private final QuarkusClassLoader.Builder classLoader; + @Inject public LiveReloadProcessor( CombinedIndexBuildItem combinedIndexBuildItem, @@ -84,10 +96,12 @@ public LiveReloadProcessor( computingIndex = combinedIndexBuildItem.getComputingIndex(); index = combinedIndexBuildItem.getIndex(); kogitoBuildContext = contextBuildItem.getKogitoBuildContext(); + classLoader = QuarkusClassLoader.builder("liveReload", kogitoBuildContext.getClassLoader(), false); } @BuildStep(onlyIf = IsDevelopment.class) - public LiveReloadExecutionBuildItem liveReload(BuildProducer sourcesProducer) { + public LiveReloadExecutionBuildItem liveReload(BuildProducer sourcesProducer, BuildProducer genResBI, + BuildProducer configBuilder) { Collection generatedFiles = new ArrayList<>(); List indexViews = new ArrayList<>(); if (liveReloadBuildItem.isLiveReload()) { @@ -103,10 +117,13 @@ public LiveReloadExecutionBuildItem liveReload(BuildProducer generatedFiles = new ArrayList<>(generateSources(codeGenProvider)); - return !generatedFiles.isEmpty() ? new CodeGenerationResult(generatedFiles, indexCompiledSources(compileGeneratedSources(generatedFiles))) + Collection generatedBeans = compileGeneratedSources(generatedFiles); + if (!generatedBeans.isEmpty()) { + classLoader.addElement(new MemoryClassPathElement( + generatedBeans.stream().collect(Collectors.toMap(x -> x.getName().replace('.', '/').concat(".class"), GeneratedBeanBuildItem::getData)), true)); + } + return !generatedFiles.isEmpty() ? new CodeGenerationResult(generatedFiles, indexCompiledSources(generatedBeans)) : new CodeGenerationResult(List.of(), computingIndex); } catch (CodeGenException e) { throw new IllegalStateException(e); @@ -159,23 +181,28 @@ private Collection generateSources(LiveReloadableCodeGenProvider CodeGenContext codeGenContext = new CodeGenContext(applicationModel, outDir, workDir, inputDir, false, config, false); if (codeGenProvider.shouldRun(inputDir, config) && codeGenProvider.trigger(codeGenContext)) { try (Stream sources = Files.walk(outDir)) { - sources.filter(Files::isRegularFile) - .filter(path -> path.toString().endsWith(".java")) - .map(path -> { - try { - return new GeneratedFile(GeneratedFileType.SOURCE, outDir.relativize(path), Files.readAllBytes(path)); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }) - .forEach(generatedFiles::add); + sources.filter(Files::isRegularFile).forEach(p -> processSource(p, outDir, generatedFiles)); + } + Path classPath = outDir.getParent().getParent().resolve("classes"); + Path serviceLoaderPath = classPath.resolve("META-INF/services"); + if (Files.isDirectory(classPath) && Files.isDirectory(serviceLoaderPath)) { + classLoader.addElement(new PathTreeClassPathElement(PathTree.ofDirectoryOrFile(classPath), true)); } } } - return generatedFiles; } + private void processSource(Path path, Path outDir, Collection generatedFiles) { + if (path.toString().endsWith(".java")) { + try { + generatedFiles.add(new GeneratedFile(GeneratedFileType.SOURCE, outDir.relativize(path), Files.readAllBytes(path))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + private void skipNextLiveReload() { liveReloadBuildItem.setContextObject(SkipLiveReload.class, SkipLiveReload.TRUE); } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml index 8c0fe4812e9..ef8ab961040 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/pom.xml @@ -43,27 +43,16 @@ io.grpc grpc-netty-shaded - ${version.io.grpc} runtime io.grpc grpc-protobuf - ${version.io.grpc} io.grpc grpc-stub - ${version.io.grpc} - - - org.apache.tomcat - annotations-api - 6.0.53 - provided - - io.quarkus quarkus-junit5 diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java index 7d8a4793aa3..a9909433baf 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-extension-live-reload-test/src/test/java/org/kie/kogito/quarkus/serverless/workflow/deployment/livereload/LiveReloadProcessorTest.java @@ -28,7 +28,6 @@ import org.jboss.shrinkwrap.api.asset.StringAsset; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.kie.kogito.test.utils.SocketUtils; @@ -163,7 +162,6 @@ void testGrpc() throws InterruptedException, IOException { } @Test - @Disabled("Disabled until https://issues.redhat.com/browse/KOGITO-9614 is resolved") void testAsyncApi() throws IOException { given() .contentType(ContentType.JSON) diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/quarkus/serverless/workflow/config/LiveReloadConfigBuilder.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/quarkus/serverless/workflow/config/LiveReloadConfigBuilder.java new file mode 100644 index 00000000000..f7a558d30ac --- /dev/null +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow/src/main/java/org/kie/kogito/quarkus/serverless/workflow/config/LiveReloadConfigBuilder.java @@ -0,0 +1,27 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates. + * + * Licensed 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.quarkus.serverless.workflow.config; + +import io.quarkus.runtime.configuration.ConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilder; + +public class LiveReloadConfigBuilder implements ConfigBuilder { + + @Override + public SmallRyeConfigBuilder configBuilder(SmallRyeConfigBuilder builder) { + return builder.addDiscoveredSources(); + } +} From 325da9a327237883513e8f4154a7d8bde76f020c Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Tue, 8 Aug 2023 17:44:06 +0200 Subject: [PATCH 3/3] [KOGITO-9614] Changes after CI run --- .../common/message/CloudEventHttpOutgoingDecorator.java | 2 +- .../quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/quarkus/addons/messaging/common/src/main/java/org/kie/kogito/addon/quarkus/messaging/common/message/CloudEventHttpOutgoingDecorator.java b/quarkus/addons/messaging/common/src/main/java/org/kie/kogito/addon/quarkus/messaging/common/message/CloudEventHttpOutgoingDecorator.java index 9de0c4cb5bf..53c35657ad6 100644 --- a/quarkus/addons/messaging/common/src/main/java/org/kie/kogito/addon/quarkus/messaging/common/message/CloudEventHttpOutgoingDecorator.java +++ b/quarkus/addons/messaging/common/src/main/java/org/kie/kogito/addon/quarkus/messaging/common/message/CloudEventHttpOutgoingDecorator.java @@ -25,7 +25,7 @@ /** * Decorators for Http CloudEvents outgoing messages */ -public final class CloudEventHttpOutgoingDecorator implements MessageDecorator { +public class CloudEventHttpOutgoingDecorator implements MessageDecorator { // Note: this constant is also declared in cloudevents-json-jackson. // However, to avoid importing a library for only one constant that won't likely to change, we opt to have it declared here. diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java index 61b88efad31..fe81109150e 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/quarkus/serverless/workflow/asyncapi/AsyncAPIProcessor.java @@ -30,7 +30,7 @@ public class AsyncAPIProcessor { @BuildStep - void asyncAPIContext(LiveReloadExecutionBuildItem reload, KogitoBuildContextBuildItem context, BuildProducer sources) throws ClassNotFoundException { + void asyncAPIContext(LiveReloadExecutionBuildItem reload, KogitoBuildContextBuildItem context, BuildProducer sources) { context.getKogitoBuildContext().addContextAttribute(ParserContext.ASYNC_CONVERTER_KEY, new AsyncAPIInfoConverter( new MapAsyncAPIRegistry(ServiceLoader.load(AsyncAPISupplier.class, reload.getClassLoader().orElse(Thread.currentThread().getContextClassLoader()))))); }