From 76b1b534f0614353c5137c8db7eac7bba6977d17 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Tue, 18 Jul 2023 18:34:05 +0200 Subject: [PATCH] [KOGITO-9584] Support id --- .../utils/ServerlessWorkflowUtils.java | 8 +- .../workflow/io/URIContentLoaderFactory.java | 92 +++++++++++++++++-- .../workflow/io/URIContentLoaderType.java | 6 +- .../parser/schema/JsonSchemaImpl.java | 9 +- .../workflow/parser/schema/RefSchemas.java | 9 ++ 5 files changed, 104 insertions(+), 20 deletions(-) diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/ServerlessWorkflowUtils.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/ServerlessWorkflowUtils.java index 4795b1e00ef..7c9de936772 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/ServerlessWorkflowUtils.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/ServerlessWorkflowUtils.java @@ -36,6 +36,7 @@ import org.kie.kogito.serverless.workflow.extensions.OutputSchema; import org.kie.kogito.serverless.workflow.extensions.URIDefinitions; import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory; +import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory.Builder; import org.kie.kogito.serverless.workflow.models.JsonNodeModel; import org.kie.kogito.serverless.workflow.parser.ParserContext; import org.kie.kogito.serverless.workflow.suppliers.ConfigWorkItemSupplier; @@ -195,9 +196,10 @@ public static Optional loadResourceFile(Workflow workflow, Optional loadResourceFile(String uriStr, Optional workflow, Optional parserContext, String authRef) { final URI uri = URI.create(uriStr); try { - final byte[] bytes = - URIContentLoaderFactory.readAllBytes(URIContentLoaderFactory.loader(uri, parserContext.map(p -> p.getContext().getClassLoader()), Optional.empty(), workflow, authRef)); - return Optional.of(bytes); + Builder builder = URIContentLoaderFactory.builder(uri).withAuthRef(authRef); + workflow.ifPresent(builder::withWorkflow); + parserContext.map(p -> p.getContext().getClassLoader()).ifPresent(builder::withClassloader); + return Optional.of(URIContentLoaderFactory.readAllBytes(builder.build())); } catch (UncheckedIOException io) { // if file cannot be found in build context, warn it and return the unmodified uri (it might be possible that later the resource is available at runtime) logger.warn("Resource {} cannot be found at build time, ignoring", uri, io); diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java index ce374d33d2f..7013f0a93cd 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java @@ -35,23 +35,95 @@ public static byte[] readAllBytes(URIContentLoader loader) { public static URIContentLoader runtimeLoader(String uriStr) { URI uri = URI.create(uriStr); - return loader(uri, Optional.empty(), Optional.of(new ClassPathContentLoader(uri, Optional.empty())), Optional.empty(), null); + Builder builder = new Builder(uri); + builder.withFallback(new ClassPathContentLoader(uri, Optional.empty())); + return builder.build(); + } public static URIContentLoader buildLoader(URI uri, ClassLoader cl, Workflow workflow, String authRef) { - return loader(uri, Optional.of(cl), Optional.empty(), Optional.of(workflow), authRef); + return new Builder(uri).withClassloader(cl).withWorkflow(workflow).withAuthRef(authRef).build(); } + /** + * @deprecated Use builder + */ + @Deprecated public static URIContentLoader loader(URI uri, Optional cl, Optional fallback, Optional workflow, String authRef) { - switch (URIContentLoaderType.from(uri)) { - case FILE: - return new FileContentLoader(uri, fallback); - case HTTP: - return new HttpContentLoader(uri, fallback, workflow, authRef); - default: - case CLASSPATH: - return new ClassPathContentLoader(uri, cl); + Builder builder = new Builder(uri); + cl.ifPresent(builder::withClassloader); + fallback.ifPresent(builder::withFallback); + workflow.ifPresent(builder::withWorkflow); + builder.withAuthRef(authRef); + return builder.build(); + } + + public static Builder builder(URI uri) { + return new Builder(uri); + } + + public static class Builder { + private URI uri; + private ClassLoader cl; + private URIContentLoader fallback; + private Workflow workflow; + private String authRef; + private URI baseURI; + + private Builder(URI uri) { + this.uri = uri; + } + + public Builder withClassloader(ClassLoader cl) { + this.cl = cl; + return this; + } + + public Builder withFallback(URIContentLoader fallback) { + this.fallback = fallback; + return this; } + + public Builder withWorkflow(Workflow workflow) { + this.workflow = workflow; + return this; + } + + public Builder withAuthRef(String authRef) { + this.authRef = authRef; + return this; + } + + public Builder withBaseURI(String baseURI) { + if (baseURI != null) { + int lastIndexOf = baseURI.lastIndexOf('/'); + this.baseURI = URI.create(lastIndexOf != -1 ? baseURI.substring(0, lastIndexOf) : baseURI); + } + return this; + } + + public URIContentLoader build() { + if (uri.getScheme() == null) { + if (baseURI != null) { + uri = compoundURI(baseURI, uri); + } else { + return new ClassPathContentLoader(uri, Optional.ofNullable(cl)); + } + } + switch (URIContentLoaderType.from(uri)) { + case FILE: + return new FileContentLoader(uri, Optional.ofNullable(fallback)); + case HTTP: + return new HttpContentLoader(uri, Optional.ofNullable(fallback), Optional.ofNullable(workflow), authRef); + default: + case CLASSPATH: + return new ClassPathContentLoader(uri, Optional.ofNullable(cl)); + } + } + } + + private static URI compoundURI(URI baseURI, URI uri) { + return URI.create(baseURI.toString() + "/" + uri.toString()); } private URIContentLoaderFactory() { diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderType.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderType.java index 3920305bf46..1f17aefccca 100644 --- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderType.java +++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderType.java @@ -20,12 +20,10 @@ public enum URIContentLoaderType { CLASSPATH, FILE, - HTTP; + HTTP, + DEFAULT; public static URIContentLoaderType from(URI uri) { - if (uri.getScheme() == null) { - return CLASSPATH; - } switch (uri.getScheme().toLowerCase()) { case "file": return FILE; diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/JsonSchemaImpl.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/JsonSchemaImpl.java index abda815211d..60fd6221afc 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/JsonSchemaImpl.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/JsonSchemaImpl.java @@ -22,7 +22,6 @@ import java.net.URISyntaxException; import java.util.List; import java.util.Map; -import java.util.Optional; import org.eclipse.microprofile.openapi.models.media.Schema; import org.kie.kogito.jackson.utils.ObjectMapperFactory; @@ -48,11 +47,16 @@ public class JsonSchemaImpl extends SchemaImpl { private static final Logger logger = LoggerFactory.getLogger(JsonSchemaImpl.class); + @JsonSetter("$id") + public void setId(String id) { + RefSchemas.baseURI(id); + } + @JsonSetter("$ref") @Override public void setRef(String ref) { if (ref != null && !ref.startsWith("#")) { - try (InputStream is = URIContentLoaderFactory.loader(new URI(ref), Optional.empty(), Optional.empty(), Optional.empty(), null).getInputStream()) { + try (InputStream is = URIContentLoaderFactory.builder(new URI(ref)).withBaseURI(RefSchemas.getBaseURI()).build().getInputStream()) { JsonSchemaImpl schema = ObjectMapperFactory.get().readValue(is.readAllBytes(), JsonSchemaImpl.class); String key; if (schema.getTitle() == null) { @@ -114,5 +118,4 @@ public Schema getAdditionalPropertiesSchema() { public Schema getNot() { return super.getNot(); } - } diff --git a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/RefSchemas.java b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/RefSchemas.java index 3020acf1562..04291d6ce43 100644 --- a/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/RefSchemas.java +++ b/quarkus/extensions/kogito-quarkus-serverless-workflow-extension/kogito-quarkus-serverless-workflow-deployment/src/main/java/org/kie/kogito/serverless/workflow/parser/schema/RefSchemas.java @@ -30,6 +30,7 @@ private static class ThreadInfo { private final String id; private final Map map = new HashMap<>(); private int counter; + private String baseURI; private ThreadInfo(String id) { this.id = id; @@ -46,6 +47,14 @@ public static Map get() { return threadInfo.get().map; } + public static void baseURI(String baseURI) { + threadInfo.get().baseURI = baseURI; + } + + public static String getBaseURI() { + return threadInfo.get().baseURI; + } + public static String getKey() { ThreadInfo t = threadInfo.get(); return t.id + "_nested_" + ++t.counter;