diff --git a/kogito-build/kogito-dependencies-bom/pom.xml b/kogito-build/kogito-dependencies-bom/pom.xml index 4c79cc0340b..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.5 + 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 a433dfae7ad..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 @@ -215,7 +215,7 @@ 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) { + } catch (Exception 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 537db0ce99d..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 @@ -16,6 +16,7 @@ package org.kie.kogito.codegen.process; public class ProcessParsingException extends RuntimeException { + private static final long serialVersionUID = 1L; public ProcessParsingException(Throwable cause) { 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/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 4419cb7a659..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 @@ -40,6 +40,7 @@ import com.github.javaparser.ast.CompilationUnit; +import io.quarkus.deployment.CodeGenContext; import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.functions.FunctionDefinition; @@ -51,8 +52,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) { 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..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 @@ -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) { + 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/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/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-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..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 @@ -53,7 +53,6 @@ io.grpc grpc-stub - io.quarkus quarkus-junit5 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(); + } +}