From 9a0396436450eb59311f9bd2fe81d977225dab9b Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Thu, 6 Jul 2023 14:27:27 +0200 Subject: [PATCH 01/33] Removing gson and everit dependencies Signed-off-by: Francisco Javier Tirado Sarti Signed-off-by: Ricardo Zanini --- api/pom.xml | 9 - .../api/deserializers/AuthDeserializer.java | 17 +- .../deserializers/ConstantsDeserializer.java | 18 +- .../api/deserializers/ErrorsDeserializer.java | 17 +- .../api/deserializers/EventsDeserializer.java | 16 +- .../deserializers/FunctionsDeserializer.java | 15 +- .../deserializers/RetriesDeserializer.java | 17 +- .../deserializers/SecretsDeserializer.java | 17 +- .../api/interfaces/WorkflowValidator.java | 4 +- .../api/mapper/JsonObjectMapperFactory.java | 27 ++ .../api/mapper/YamlObjectMapperFactory.java | 27 ++ .../schemaclient/ResourceSchemaClient.java | 38 -- .../serverlessworkflow/api/utils/Utils.java | 15 + .../api/validation/ValidationError.java | 16 + .../api/validation/WorkflowSchemaLoader.java | 33 +- pom.xml | 23 +- validation/pom.xml | 7 +- .../validation/WorkflowValidatorImpl.java | 445 +++++++++--------- .../test/WorkflowValidationTest.java | 75 +-- 19 files changed, 375 insertions(+), 461 deletions(-) create mode 100644 api/src/main/java/io/serverlessworkflow/api/mapper/JsonObjectMapperFactory.java create mode 100644 api/src/main/java/io/serverlessworkflow/api/mapper/YamlObjectMapperFactory.java delete mode 100644 api/src/main/java/io/serverlessworkflow/api/schemaclient/ResourceSchemaClient.java diff --git a/api/pom.xml b/api/pom.xml index 8b27e853..67f19e47 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,15 +42,6 @@ javax.validation validation-api - - org.json - json - - - com.github.erosb - everit-json-schema - - org.junit.jupiter diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDeserializer.java index abdb0583..aa078cb4 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDeserializer.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.auth.AuthDefinition; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; @@ -28,7 +27,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,21 +67,8 @@ public Auth deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExc } else { String authFileDef = node.asText(); String authFileSrc = Utils.getResourceFileAsString(authFileDef); - JsonNode authRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (authFileSrc != null && authFileSrc.trim().length() > 0) { - // if its a yaml def convert to json first - if (!authFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(authFileSrc, Object.class); - - authRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - authRefNode = jsonWriter.readTree(new JSONObject(authFileSrc).toString()); - } - + JsonNode authRefNode = Utils.getNode(authFileSrc); JsonNode refAuth = authRefNode.get("auth"); if (refAuth != null) { for (final JsonNode nodeEle : refAuth) { diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/ConstantsDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/ConstantsDeserializer.java index c3789b52..3859273c 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/ConstantsDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/ConstantsDeserializer.java @@ -18,14 +18,11 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; import io.serverlessworkflow.api.workflow.Constants; import java.io.IOException; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,21 +60,8 @@ public Constants deserialize(JsonParser jp, DeserializationContext ctxt) throws } else { String constantsFileDef = node.asText(); String constantsFileSrc = Utils.getResourceFileAsString(constantsFileDef); - JsonNode constantsRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (constantsFileSrc != null && constantsFileSrc.trim().length() > 0) { - // if its a yaml def convert to json first - if (!constantsFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(constantsFileSrc, Object.class); - - constantsRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - constantsRefNode = jsonWriter.readTree(new JSONObject(constantsFileSrc).toString()); - } - + JsonNode constantsRefNode = Utils.getNode(constantsFileSrc); JsonNode refConstants = constantsRefNode.get("constants"); if (refConstants != null) { constantsDefinition = refConstants; diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/ErrorsDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/ErrorsDeserializer.java index beedc7dd..6fe366ea 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/ErrorsDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/ErrorsDeserializer.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.error.ErrorDefinition; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; @@ -28,7 +27,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,21 +67,8 @@ public Errors deserialize(JsonParser jp, DeserializationContext ctxt) throws IOE } else { String errorsFileDef = node.asText(); String errorsFileSrc = Utils.getResourceFileAsString(errorsFileDef); - JsonNode errorsRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (errorsFileSrc != null && errorsFileSrc.trim().length() > 0) { - // if its a yaml def convert to json first - if (!errorsFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(errorsFileSrc, Object.class); - - errorsRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - errorsRefNode = jsonWriter.readTree(new JSONObject(errorsFileSrc).toString()); - } - + JsonNode errorsRefNode = Utils.getNode(errorsFileSrc); JsonNode refErrors = errorsRefNode.get("errors"); if (refErrors != null) { for (final JsonNode nodeEle : refErrors) { diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/EventsDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/EventsDeserializer.java index cfa207df..a02fdf4b 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/EventsDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/EventsDeserializer.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.events.EventDefinition; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; @@ -28,7 +27,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,21 +67,9 @@ public Events deserialize(JsonParser jp, DeserializationContext ctxt) throws IOE } else { String eventsFileDef = node.asText(); String eventsFileSrc = Utils.getResourceFileAsString(eventsFileDef); - JsonNode eventsRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (eventsFileSrc != null && eventsFileSrc.trim().length() > 0) { // if its a yaml def convert to json first - if (!eventsFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(eventsFileSrc, Object.class); - - eventsRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - eventsRefNode = jsonWriter.readTree(new JSONObject(eventsFileSrc).toString()); - } - + JsonNode eventsRefNode = Utils.getNode(eventsFileSrc); JsonNode refEvents = eventsRefNode.get("events"); if (refEvents != null) { for (final JsonNode nodeEle : refEvents) { diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/FunctionsDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/FunctionsDeserializer.java index c27e2c48..b706b2d3 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/FunctionsDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/FunctionsDeserializer.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.functions.FunctionDefinition; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; @@ -28,7 +27,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,20 +67,9 @@ public Functions deserialize(JsonParser jp, DeserializationContext ctxt) throws String functionsFileDef = node.asText(); String functionsFileSrc = Utils.getResourceFileAsString(functionsFileDef); JsonNode functionsRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (functionsFileSrc != null && functionsFileSrc.trim().length() > 0) { // if its a yaml def convert to json first - if (!functionsFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(functionsFileSrc, Object.class); - - functionsRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - functionsRefNode = jsonWriter.readTree(new JSONObject(functionsFileSrc).toString()); - } - + functionsRefNode = Utils.getNode(functionsFileSrc); JsonNode refFunctions = functionsRefNode.get("functions"); if (refFunctions != null) { for (final JsonNode nodeEle : refFunctions) { diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java index ff2fe44d..66f9e1b7 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.retry.RetryDefinition; import io.serverlessworkflow.api.utils.Utils; @@ -28,7 +27,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,21 +67,10 @@ public Retries deserialize(JsonParser jp, DeserializationContext ctxt) throws IO } else { String retriesFileDef = node.asText(); String retriesFileSrc = Utils.getResourceFileAsString(retriesFileDef); - JsonNode retriesRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); + ; if (retriesFileSrc != null && retriesFileSrc.trim().length() > 0) { // if its a yaml def convert to json first - if (!retriesFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(retriesFileSrc, Object.class); - - retriesRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - retriesRefNode = jsonWriter.readTree(new JSONObject(retriesFileSrc).toString()); - } - + JsonNode retriesRefNode = Utils.getNode(retriesFileSrc); JsonNode refRetries = retriesRefNode.get("retries"); if (refRetries != null) { for (final JsonNode nodeEle : refRetries) { diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/SecretsDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/SecretsDeserializer.java index e9ec05e7..60cc2a82 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/SecretsDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/SecretsDeserializer.java @@ -18,16 +18,13 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; import io.serverlessworkflow.api.utils.Utils; import io.serverlessworkflow.api.workflow.Secrets; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,21 +63,9 @@ public Secrets deserialize(JsonParser jp, DeserializationContext ctxt) throws IO } else { String secretsFileDef = node.asText(); String secretsFileSrc = Utils.getResourceFileAsString(secretsFileDef); - JsonNode secretsRefNode; - ObjectMapper jsonWriter = new ObjectMapper(); if (secretsFileSrc != null && secretsFileSrc.trim().length() > 0) { // if its a yaml def convert to json first - if (!secretsFileSrc.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(secretsFileSrc, Object.class); - - secretsRefNode = - jsonWriter.readTree(new JSONObject(jsonWriter.writeValueAsString(obj)).toString()); - } else { - secretsRefNode = jsonWriter.readTree(new JSONObject(secretsFileSrc).toString()); - } - + JsonNode secretsRefNode = Utils.getNode(secretsFileSrc); JsonNode refSecrets = secretsRefNode.get("secrets"); if (refSecrets != null) { for (final JsonNode nodeEle : refSecrets) { diff --git a/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java b/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java index 199a0927..09c79066 100644 --- a/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java +++ b/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java @@ -17,7 +17,7 @@ import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.validation.ValidationError; -import java.util.List; +import java.util.Collection; public interface WorkflowValidator { @@ -25,7 +25,7 @@ public interface WorkflowValidator { WorkflowValidator setSource(String source); - List validate(); + Collection validate(); boolean isValid(); diff --git a/api/src/main/java/io/serverlessworkflow/api/mapper/JsonObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/mapper/JsonObjectMapperFactory.java new file mode 100644 index 00000000..eb34b0eb --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/mapper/JsonObjectMapperFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.api.mapper; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonObjectMapperFactory { + + private static final ObjectMapper instance = new JsonObjectMapper(); + + public static final ObjectMapper mapper() { + return instance; + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/mapper/YamlObjectMapperFactory.java b/api/src/main/java/io/serverlessworkflow/api/mapper/YamlObjectMapperFactory.java new file mode 100644 index 00000000..04371db4 --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/mapper/YamlObjectMapperFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.api.mapper; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class YamlObjectMapperFactory { + + private static final ObjectMapper instance = new YamlObjectMapper(); + + public static final ObjectMapper mapper() { + return instance; + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/schemaclient/ResourceSchemaClient.java b/api/src/main/java/io/serverlessworkflow/api/schemaclient/ResourceSchemaClient.java deleted file mode 100644 index a4da2387..00000000 --- a/api/src/main/java/io/serverlessworkflow/api/schemaclient/ResourceSchemaClient.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * 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 io.serverlessworkflow.api.schemaclient; - -import java.io.InputStream; -import java.util.Objects; -import org.everit.json.schema.loader.SchemaClient; - -public class ResourceSchemaClient implements SchemaClient { - - @SuppressWarnings("unused") - private final SchemaClient fallbackClient; - - private final String baseResourcePath = "/schema/"; - - public ResourceSchemaClient(SchemaClient fallbackClient) { - this.fallbackClient = Objects.requireNonNull(fallbackClient, "fallbackClient cannot be null"); - } - - @Override - public InputStream get(String path) { - path = path.substring("https://wg-serverless.org/".length()); - return this.getClass().getResourceAsStream(baseResourcePath + path); - } -} diff --git a/api/src/main/java/io/serverlessworkflow/api/utils/Utils.java b/api/src/main/java/io/serverlessworkflow/api/utils/Utils.java index 3e4b4274..9bdce416 100644 --- a/api/src/main/java/io/serverlessworkflow/api/utils/Utils.java +++ b/api/src/main/java/io/serverlessworkflow/api/utils/Utils.java @@ -15,6 +15,11 @@ */ package io.serverlessworkflow.api.utils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.serverlessworkflow.api.mapper.JsonObjectMapperFactory; +import io.serverlessworkflow.api.mapper.YamlObjectMapperFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -34,4 +39,14 @@ public static String getResourceFileAsString(String fileName) throws IOException } } } + + public static ObjectMapper getObjectMapper(String source) { + return !source.trim().startsWith("{") + ? YamlObjectMapperFactory.mapper() + : JsonObjectMapperFactory.mapper(); + } + + public static JsonNode getNode(String source) throws JsonProcessingException { + return getObjectMapper(source).readTree(source); + } } diff --git a/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java b/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java index edb92eff..2aebccf9 100644 --- a/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java +++ b/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java @@ -15,6 +15,8 @@ */ package io.serverlessworkflow.api.validation; +import java.util.Objects; + public class ValidationError { private static final String MSG_FORMAT = "%s:%s"; public static final String SCHEMA_VALIDATION = "schemavalidation"; @@ -43,4 +45,18 @@ public void setType(String type) { public String toString() { return String.format(MSG_FORMAT, type, message); } + + @Override + public int hashCode() { + return Objects.hash(message, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + ValidationError other = (ValidationError) obj; + return Objects.equals(message, other.message) && Objects.equals(type, other.type); + } } diff --git a/api/src/main/java/io/serverlessworkflow/api/validation/WorkflowSchemaLoader.java b/api/src/main/java/io/serverlessworkflow/api/validation/WorkflowSchemaLoader.java index 830bb50a..847380fb 100644 --- a/api/src/main/java/io/serverlessworkflow/api/validation/WorkflowSchemaLoader.java +++ b/api/src/main/java/io/serverlessworkflow/api/validation/WorkflowSchemaLoader.java @@ -15,26 +15,23 @@ */ package io.serverlessworkflow.api.validation; -import io.serverlessworkflow.api.schemaclient.ResourceSchemaClient; -import org.everit.json.schema.Schema; -import org.everit.json.schema.loader.SchemaLoader; -import org.everit.json.schema.loader.internal.DefaultSchemaClient; -import org.json.JSONObject; -import org.json.JSONTokener; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.UncheckedIOException; public class WorkflowSchemaLoader { - private static final JSONObject workflowSchema = - new JSONObject( - new JSONTokener(WorkflowSchemaLoader.class.getResourceAsStream("/schema/workflow.json"))); - public static Schema getWorkflowSchema() { - SchemaLoader schemaLoader = - SchemaLoader.builder() - .schemaClient(new ResourceSchemaClient(new DefaultSchemaClient())) - .schemaJson(workflowSchema) - .resolutionScope("classpath:schema") - .draftV7Support() - .build(); - return schemaLoader.load().build(); + public static JsonNode getWorkflowSchema() { + try { + return ObjectMapperHolder.objectMapper.readTree( + WorkflowSchemaLoader.class.getResourceAsStream("/schema/workflow.json")); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private static class ObjectMapperHolder { + public static final ObjectMapper objectMapper = new ObjectMapper(); } } diff --git a/pom.xml b/pom.xml index 53a2abf3..eb36b90f 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,7 @@ 1.7.25 2.10.3 2.0.1.Final + 2.2.14 6.0 5.${version.org.junit.minor} ${version.org.junit} @@ -73,7 +74,6 @@ 1.3 1.5.0 1.14.1 - 20230618 3.0.11.RELEASE 8059 0.17.0 @@ -125,6 +125,11 @@ jackson-databind ${version.com.fasterxml.jackson} + + com.github.java-json-tools + json-schema-validator + ${version.com.github.java-json-tools} + com.fasterxml.jackson.dataformat jackson-dataformat-yaml @@ -140,22 +145,6 @@ commons-lang3 ${commons.lang.version} - - com.github.erosb - everit-json-schema - ${json.schema.validation.version} - - - commons-logging - commons-logging - - - - - org.json - json - ${version.json} - org.thymeleaf thymeleaf diff --git a/validation/pom.xml b/validation/pom.xml index 57afbbb5..c47449a9 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -35,11 +35,10 @@ commons-lang3 - - com.github.erosb - everit-json-schema + + com.github.java-json-tools + json-schema-validator - org.junit.jupiter diff --git a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java index abef046b..1e7022f4 100644 --- a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java +++ b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java @@ -15,8 +15,9 @@ */ package io.serverlessworkflow.validation; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.databind.JsonNode; +import com.github.fge.jsonschema.core.exceptions.ProcessingException; +import com.github.fge.jsonschema.main.JsonSchemaFactory; import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.actions.Action; import io.serverlessworkflow.api.events.EventDefinition; @@ -27,15 +28,15 @@ import io.serverlessworkflow.api.states.*; import io.serverlessworkflow.api.switchconditions.DataCondition; import io.serverlessworkflow.api.switchconditions.EventCondition; +import io.serverlessworkflow.api.utils.Utils; import io.serverlessworkflow.api.validation.ValidationError; import io.serverlessworkflow.api.validation.WorkflowSchemaLoader; -import java.util.ArrayList; +import java.io.IOException; +import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import org.everit.json.schema.Schema; -import org.everit.json.schema.ValidationException; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,8 +44,8 @@ public class WorkflowValidatorImpl implements WorkflowValidator { private static final Logger logger = LoggerFactory.getLogger(WorkflowValidatorImpl.class); private boolean schemaValidationEnabled = true; - private List validationErrors = new ArrayList<>(); - private Schema workflowSchema = WorkflowSchemaLoader.getWorkflowSchema(); + private Collection validationErrors = new LinkedHashSet<>(); + private JsonNode workflowSchema = WorkflowSchemaLoader.getWorkflowSchema(); private String source; private Workflow workflow; @@ -61,39 +62,16 @@ public WorkflowValidator setSource(String source) { } @Override - public List validate() { + public Collection validate() { validationErrors.clear(); - if (workflow == null) { + if (workflow == null && schemaValidationEnabled && source != null) { try { - if (schemaValidationEnabled && source != null) { - try { - if (!source.trim().startsWith("{")) { - // convert yaml to json to validate - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(source, Object.class); - - ObjectMapper jsonWriter = new ObjectMapper(); - - workflowSchema.validate(new JSONObject(jsonWriter.writeValueAsString(obj))); - } else { - workflowSchema.validate(new JSONObject(source)); - } - } catch (ValidationException e) { - e.getCausingExceptions().stream() - .map(ValidationException::getMessage) - .forEach( - m -> { - if ((!m.equals("#/functions: expected type: JSONObject, found: JSONArray") - && !m.equals("#/events: expected type: JSONObject, found: JSONArray") - && !m.equals("#/start: expected type: JSONObject, found: String") - && !m.equals("#/retries: expected type: JSONObject, found: JSONArray"))) { - addValidationError(m, ValidationError.SCHEMA_VALIDATION); - } - }); - } - } - } catch (Exception e) { - logger.error("Schema validation exception: " + e.getMessage()); + JsonSchemaFactory.byDefault() + .getJsonSchema(workflowSchema) + .validate(Utils.getNode(source)) + .forEach(m -> addValidationError(m.getMessage(), ValidationError.SCHEMA_VALIDATION)); + } catch (ProcessingException | IOException e) { + logger.error("Unexpected error during validation", e); } } @@ -101,258 +79,255 @@ public List validate() { // there is no point of doing the workflow validation if (validationErrors.size() > 0) { return validationErrors; - } else { - if (workflow == null) { - workflow = Workflow.fromSource(source); - } + } else if (workflow == null) { + workflow = Workflow.fromSource(source); + } - List functions = - workflow.getFunctions() != null ? workflow.getFunctions().getFunctionDefs() : null; + List functions = + workflow.getFunctions() != null ? workflow.getFunctions().getFunctionDefs() : null; - List events = - workflow.getEvents() != null ? workflow.getEvents().getEventDefs() : null; + List events = + workflow.getEvents() != null ? workflow.getEvents().getEventDefs() : null; - if ((workflow.getId() == null || workflow.getId().trim().isEmpty()) - && (workflow.getKey() == null || workflow.getKey().trim().isEmpty())) { - addValidationError( - "Workflow id or key should not be empty", ValidationError.WORKFLOW_VALIDATION); - } + if ((workflow.getId() == null || workflow.getId().trim().isEmpty()) + && (workflow.getKey() == null || workflow.getKey().trim().isEmpty())) { + addValidationError( + "Workflow id or key should not be empty", ValidationError.WORKFLOW_VALIDATION); + } - if (workflow.getVersion() == null || workflow.getVersion().trim().isEmpty()) { - addValidationError( - "Workflow version should not be empty", ValidationError.WORKFLOW_VALIDATION); - } + if (workflow.getVersion() == null || workflow.getVersion().trim().isEmpty()) { + addValidationError( + "Workflow version should not be empty", ValidationError.WORKFLOW_VALIDATION); + } - if (workflow.getStates() == null || workflow.getStates().isEmpty()) { - addValidationError("No states found", ValidationError.WORKFLOW_VALIDATION); - } + if (workflow.getStates() == null || workflow.getStates().isEmpty()) { + addValidationError("No states found", ValidationError.WORKFLOW_VALIDATION); + } - if (workflow.getStates() != null && !workflow.getStates().isEmpty()) { - boolean existingStateWithStartProperty = false; - if (workflow.getStart() != null) { - String startProperty = workflow.getStart().getStateName(); - for (State s : workflow.getStates()) { - if (s.getName().equals(startProperty)) { - existingStateWithStartProperty = true; - break; - } + if (workflow.getStates() != null && !workflow.getStates().isEmpty()) { + boolean existingStateWithStartProperty = false; + if (workflow.getStart() != null) { + String startProperty = workflow.getStart().getStateName(); + for (State s : workflow.getStates()) { + if (s.getName().equals(startProperty)) { + existingStateWithStartProperty = true; + break; } - } else { - existingStateWithStartProperty = true; - } - if (!existingStateWithStartProperty) { - addValidationError( - "No state name found that matches the workflow start definition", - ValidationError.WORKFLOW_VALIDATION); } + } else { + existingStateWithStartProperty = true; } + if (!existingStateWithStartProperty) { + addValidationError( + "No state name found that matches the workflow start definition", + ValidationError.WORKFLOW_VALIDATION); + } + } - Validation validation = new Validation(); - if (workflow.getStates() != null && !workflow.getStates().isEmpty()) { - workflow - .getStates() - .forEach( - s -> { - if (s.getName() != null && s.getName().trim().isEmpty()) { - addValidationError( - "State name should not be empty", ValidationError.WORKFLOW_VALIDATION); - } else { - validation.addState(s.getName()); - } - - if (s.getEnd() != null) { - validation.addEndState(); - } - - if (s instanceof OperationState) { - OperationState operationState = (OperationState) s; - - List actions = operationState.getActions(); - for (Action action : actions) { - if (action.getFunctionRef() != null) { - if (action.getFunctionRef().getRefName().isEmpty()) { - addValidationError( - "Operation State action functionRef should not be null or empty", - ValidationError.WORKFLOW_VALIDATION); - } - - if (!haveFunctionDefinition( - action.getFunctionRef().getRefName(), functions)) { - addValidationError( - "Operation State action functionRef does not reference an existing workflow function definition", - ValidationError.WORKFLOW_VALIDATION); - } + Validation validation = new Validation(); + if (workflow.getStates() != null && !workflow.getStates().isEmpty()) { + workflow + .getStates() + .forEach( + s -> { + if (s.getName() != null && s.getName().trim().isEmpty()) { + addValidationError( + "State name should not be empty", ValidationError.WORKFLOW_VALIDATION); + } else { + validation.addState(s.getName()); + } + + if (s.getEnd() != null) { + validation.addEndState(); + } + + if (s instanceof OperationState) { + OperationState operationState = (OperationState) s; + + List actions = operationState.getActions(); + for (Action action : actions) { + if (action.getFunctionRef() != null) { + if (action.getFunctionRef().getRefName().isEmpty()) { + addValidationError( + "Operation State action functionRef should not be null or empty", + ValidationError.WORKFLOW_VALIDATION); } - if (action.getEventRef() != null) { - if (action.getEventRef().getTriggerEventRef().isEmpty()) { - addValidationError( - "Operation State action trigger eventRef does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } - - if (action.getEventRef().getResultEventRef().isEmpty()) { - addValidationError( - "Operation State action results eventRef does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } + if (!haveFunctionDefinition( + action.getFunctionRef().getRefName(), functions)) { + addValidationError( + "Operation State action functionRef does not reference an existing workflow function definition", + ValidationError.WORKFLOW_VALIDATION); + } + } - if (!haveEventsDefinition( - action.getEventRef().getTriggerEventRef(), events)) { - addValidationError( - "Operation State action trigger event def does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } + if (action.getEventRef() != null) { + if (action.getEventRef().getTriggerEventRef().isEmpty()) { + addValidationError( + "Operation State action trigger eventRef does not reference an existing workflow event definition", + ValidationError.WORKFLOW_VALIDATION); + } - if (!haveEventsDefinition( - action.getEventRef().getResultEventRef(), events)) { - addValidationError( - "Operation State action results event def does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } + if (action.getEventRef().getResultEventRef().isEmpty()) { + addValidationError( + "Operation State action results eventRef does not reference an existing workflow event definition", + ValidationError.WORKFLOW_VALIDATION); } - } - } - if (s instanceof EventState) { - EventState eventState = (EventState) s; - if (eventState.getOnEvents() == null || eventState.getOnEvents().size() < 1) { - addValidationError( - "Event State has no eventActions defined", - ValidationError.WORKFLOW_VALIDATION); - } - List eventsActionsList = eventState.getOnEvents(); - for (OnEvents onEvents : eventsActionsList) { + if (!haveEventsDefinition( + action.getEventRef().getTriggerEventRef(), events)) { + addValidationError( + "Operation State action trigger event def does not reference an existing workflow event definition", + ValidationError.WORKFLOW_VALIDATION); + } - List eventRefs = onEvents.getEventRefs(); - if (eventRefs == null || eventRefs.size() < 1) { + if (!haveEventsDefinition(action.getEventRef().getResultEventRef(), events)) { addValidationError( - "Event State eventsActions has no event refs", + "Operation State action results event def does not reference an existing workflow event definition", ValidationError.WORKFLOW_VALIDATION); - } else { - for (String eventRef : eventRefs) { - if (!haveEventsDefinition(eventRef, events)) { - addValidationError( - "Event State eventsActions eventRef does not match a declared workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } - } } } } + } - if (s instanceof SwitchState) { - SwitchState switchState = (SwitchState) s; - if ((switchState.getDataConditions() == null - || switchState.getDataConditions().size() < 1) - && (switchState.getEventConditions() == null - || switchState.getEventConditions().size() < 1)) { - addValidationError( - "Switch state should define either data or event conditions", - ValidationError.WORKFLOW_VALIDATION); - } + if (s instanceof EventState) { + EventState eventState = (EventState) s; + if (eventState.getOnEvents() == null || eventState.getOnEvents().size() < 1) { + addValidationError( + "Event State has no eventActions defined", + ValidationError.WORKFLOW_VALIDATION); + } + List eventsActionsList = eventState.getOnEvents(); + for (OnEvents onEvents : eventsActionsList) { - if (switchState.getDefaultCondition() == null) { + List eventRefs = onEvents.getEventRefs(); + if (eventRefs == null || eventRefs.size() < 1) { addValidationError( - "Switch state should define a default transition", + "Event State eventsActions has no event refs", ValidationError.WORKFLOW_VALIDATION); - } - - if (switchState.getEventConditions() != null - && switchState.getEventConditions().size() > 0) { - List eventConditions = switchState.getEventConditions(); - for (EventCondition ec : eventConditions) { - if (!haveEventsDefinition(ec.getEventRef(), events)) { + } else { + for (String eventRef : eventRefs) { + if (!haveEventsDefinition(eventRef, events)) { addValidationError( - "Switch state event condition eventRef does not reference a defined workflow event", + "Event State eventsActions eventRef does not match a declared workflow event definition", ValidationError.WORKFLOW_VALIDATION); } - if (ec.getEnd() != null) { - validation.addEndState(); - } } } + } + } + + if (s instanceof SwitchState) { + SwitchState switchState = (SwitchState) s; + if ((switchState.getDataConditions() == null + || switchState.getDataConditions().size() < 1) + && (switchState.getEventConditions() == null + || switchState.getEventConditions().size() < 1)) { + addValidationError( + "Switch state should define either data or event conditions", + ValidationError.WORKFLOW_VALIDATION); + } - if (switchState.getDataConditions() != null - && switchState.getDataConditions().size() > 0) { - List dataConditions = switchState.getDataConditions(); - for (DataCondition dc : dataConditions) { - if (dc.getEnd() != null) { - validation.addEndState(); - } + if (switchState.getDefaultCondition() == null) { + addValidationError( + "Switch state should define a default transition", + ValidationError.WORKFLOW_VALIDATION); + } + + if (switchState.getEventConditions() != null + && switchState.getEventConditions().size() > 0) { + List eventConditions = switchState.getEventConditions(); + for (EventCondition ec : eventConditions) { + if (!haveEventsDefinition(ec.getEventRef(), events)) { + addValidationError( + "Switch state event condition eventRef does not reference a defined workflow event", + ValidationError.WORKFLOW_VALIDATION); + } + if (ec.getEnd() != null) { + validation.addEndState(); } } } - if (s instanceof SleepState) { - SleepState sleepState = (SleepState) s; - if (sleepState.getDuration() == null || sleepState.getDuration().length() < 1) { - addValidationError( - "Sleep state should have a non-empty time delay", - ValidationError.WORKFLOW_VALIDATION); + if (switchState.getDataConditions() != null + && switchState.getDataConditions().size() > 0) { + List dataConditions = switchState.getDataConditions(); + for (DataCondition dc : dataConditions) { + if (dc.getEnd() != null) { + validation.addEndState(); + } } } + } - if (s instanceof ParallelState) { - ParallelState parallelState = (ParallelState) s; + if (s instanceof SleepState) { + SleepState sleepState = (SleepState) s; + if (sleepState.getDuration() == null || sleepState.getDuration().length() < 1) { + addValidationError( + "Sleep state should have a non-empty time delay", + ValidationError.WORKFLOW_VALIDATION); + } + } - if (parallelState.getBranches() == null - || parallelState.getBranches().size() < 2) { - addValidationError( - "Parallel state should have at lest two branches", - ValidationError.WORKFLOW_VALIDATION); - } + if (s instanceof ParallelState) { + ParallelState parallelState = (ParallelState) s; + + if (parallelState.getBranches() == null + || parallelState.getBranches().size() < 2) { + addValidationError( + "Parallel state should have at lest two branches", + ValidationError.WORKFLOW_VALIDATION); } + } - if (s instanceof InjectState) { - InjectState injectState = (InjectState) s; - if (injectState.getData() == null || injectState.getData().isEmpty()) { - addValidationError( - "InjectState should have non-null data", - ValidationError.WORKFLOW_VALIDATION); - } + if (s instanceof InjectState) { + InjectState injectState = (InjectState) s; + if (injectState.getData() == null || injectState.getData().isEmpty()) { + addValidationError( + "InjectState should have non-null data", + ValidationError.WORKFLOW_VALIDATION); } + } - if (s instanceof ForEachState) { - ForEachState forEachState = (ForEachState) s; - if (forEachState.getInputCollection() == null - || forEachState.getInputCollection().isEmpty()) { - addValidationError( - "ForEach state should have a valid inputCollection", - ValidationError.WORKFLOW_VALIDATION); - } + if (s instanceof ForEachState) { + ForEachState forEachState = (ForEachState) s; + if (forEachState.getInputCollection() == null + || forEachState.getInputCollection().isEmpty()) { + addValidationError( + "ForEach state should have a valid inputCollection", + ValidationError.WORKFLOW_VALIDATION); } + } - if (s instanceof CallbackState) { - CallbackState callbackState = (CallbackState) s; + if (s instanceof CallbackState) { + CallbackState callbackState = (CallbackState) s; - if (!haveEventsDefinition(callbackState.getEventRef(), events)) { - addValidationError( - "CallbackState event ref does not reference a defined workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } + if (!haveEventsDefinition(callbackState.getEventRef(), events)) { + addValidationError( + "CallbackState event ref does not reference a defined workflow event definition", + ValidationError.WORKFLOW_VALIDATION); + } - if (!haveFunctionDefinition( - callbackState.getAction().getFunctionRef().getRefName(), functions)) { - addValidationError( - "CallbackState action function ref does not reference a defined workflow function definition", - ValidationError.WORKFLOW_VALIDATION); - } + if (!haveFunctionDefinition( + callbackState.getAction().getFunctionRef().getRefName(), functions)) { + addValidationError( + "CallbackState action function ref does not reference a defined workflow function definition", + ValidationError.WORKFLOW_VALIDATION); } - }); + } + }); - if (validation.endStates == 0) { - addValidationError("No end state found.", ValidationError.WORKFLOW_VALIDATION); - } + if (validation.endStates == 0) { + addValidationError("No end state found.", ValidationError.WORKFLOW_VALIDATION); } - - return validationErrors; } + + return validationErrors; } @Override public boolean isValid() { - return validate().size() < 1; + return validate().isEmpty(); } @Override diff --git a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java index a81e14f6..052bc687 100644 --- a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java +++ b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java @@ -25,7 +25,7 @@ import io.serverlessworkflow.api.validation.ValidationError; import io.serverlessworkflow.validation.WorkflowValidatorImpl; import java.util.Arrays; -import java.util.List; +import java.util.Collection; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -34,7 +34,7 @@ public class WorkflowValidationTest { @Test public void testIncompleteJsonWithSchemaValidation() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator.setSource("{\n" + " \"id\": \"abc\" \n" + "}").validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(3, validationErrors.size()); @@ -43,7 +43,7 @@ public void testIncompleteJsonWithSchemaValidation() { @Test public void testIncompleteYamlWithSchemaValidation() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator.setSource("---\n" + "key: abc\n").validate(); Assertions.assertNotNull(validationErrors); System.out.println(validationErrors); @@ -66,18 +66,22 @@ public void testFromIncompleteWorkflow() { .withDuration("PT1M"))); WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = workflowValidator.setWorkflow(workflow).validate(); + Collection validationErrors = + workflowValidator.setWorkflow(workflow).validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - Assertions.assertEquals( - "No state name found that matches the workflow start definition", - validationErrors.get(0).getMessage()); + Assertions.assertTrue( + validationErrors.stream() + .anyMatch( + v -> + v.getMessage() + .equals("No state name found that matches the workflow start definition"))); } @Test public void testWorkflowMissingStates() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator .setSource( "{\n" @@ -91,13 +95,14 @@ public void testWorkflowMissingStates() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - Assertions.assertEquals("No states found", validationErrors.get(0).getMessage()); + Assertions.assertTrue( + validationErrors.stream().anyMatch(v -> v.getMessage().equals("No states found"))); } @Test public void testWorkflowMissingStatesIdAndKey() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator .setSource( "{\n" @@ -109,16 +114,20 @@ public void testWorkflowMissingStatesIdAndKey() { .validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(2, validationErrors.size()); - Assertions.assertEquals( - "Workflow id or key should not be empty", validationErrors.get(0).getMessage()); - Assertions.assertEquals("No states found", validationErrors.get(1).getMessage()); + validationErrors.stream() + .filter( + v -> + v.getMessage().equals("No states found") + || v.getMessage().equals("Workflow id or key should not be empty")) + .count(), + 2); } @Test public void testOperationStateNoFunctionRef() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator .setSource( "{\n" @@ -162,10 +171,13 @@ public void testOperationStateNoFunctionRef() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - // validationErrors.stream().forEach(v -> System.out.println(v.toString())); - Assertions.assertEquals( - "Operation State action functionRef does not reference an existing workflow function definition", - validationErrors.get(0).getMessage()); + Assertions.assertTrue( + validationErrors.stream() + .anyMatch( + v -> + v.getMessage() + .equals( + "Operation State action functionRef does not reference an existing workflow function definition"))); } @Test @@ -183,7 +195,8 @@ public void testValidateWorkflowForOptionalStartStateAndWorkflowName() { .withDuration("PT1M"))); WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = workflowValidator.setWorkflow(workflow).validate(); + Collection validationErrors = + workflowValidator.setWorkflow(workflow).validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(0, validationErrors.size()); } @@ -191,7 +204,7 @@ public void testValidateWorkflowForOptionalStartStateAndWorkflowName() { @Test public void testValidateWorkflowForOptionalIterationParam() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator .setSource( "{\n" @@ -232,15 +245,13 @@ public void testValidateWorkflowForOptionalIterationParam() { .validate(); Assertions.assertNotNull(validationErrors); - Assertions.assertEquals( - 1, - validationErrors.size()); // validation error raised for functionref not for iterationParam + Assertions.assertEquals(1, validationErrors.size()); } @Test public void testMissingFunctionRefForCallbackState() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - List validationErrors = + Collection validationErrors = workflowValidator .setSource( "{\n" @@ -274,10 +285,16 @@ public void testMissingFunctionRefForCallbackState() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(2, validationErrors.size()); Assertions.assertEquals( - "CallbackState event ref does not reference a defined workflow event definition", - validationErrors.get(0).getMessage()); - Assertions.assertEquals( - "CallbackState action function ref does not reference a defined workflow function definition", - validationErrors.get(1).getMessage()); + validationErrors.stream() + .filter( + v -> + v.getMessage() + .equals( + "CallbackState event ref does not reference a defined workflow event definition") + || v.getMessage() + .equals( + "CallbackState action function ref does not reference a defined workflow function definition")) + .count(), + 2); } } From 6fc14089457d071b42cec205d43b67e41e1b9c3f Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Thu, 6 Jul 2023 17:23:03 +0200 Subject: [PATCH 02/33] Changing to networknt Signed-off-by: Francisco Javier Tirado Sarti Signed-off-by: Ricardo Zanini --- api/pom.xml | 3 -- .../deserializers/RetriesDeserializer.java | 2 - api/src/main/resources/schema/workflow.json | 2 +- pom.xml | 19 +++++---- validation/pom.xml | 7 ++-- .../validation/WorkflowValidatorImpl.java | 41 ++++++++----------- .../test/WorkflowValidationTest.java | 9 ---- 7 files changed, 32 insertions(+), 51 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 67f19e47..63ba1ef1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -26,17 +26,14 @@ com.fasterxml.jackson.core jackson-core - [2.13.0,) com.fasterxml.jackson.core jackson-databind - [2.13.0,) com.fasterxml.jackson.dataformat jackson-dataformat-yaml - [2.13.0,) javax.validation diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java index 66f9e1b7..9eb47b5f 100644 --- a/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/RetriesDeserializer.java @@ -67,9 +67,7 @@ public Retries deserialize(JsonParser jp, DeserializationContext ctxt) throws IO } else { String retriesFileDef = node.asText(); String retriesFileSrc = Utils.getResourceFileAsString(retriesFileDef); - ; if (retriesFileSrc != null && retriesFileSrc.trim().length() > 0) { - // if its a yaml def convert to json first JsonNode retriesRefNode = Utils.getNode(retriesFileSrc); JsonNode refRetries = retriesRefNode.get("retries"); if (refRetries != null) { diff --git a/api/src/main/resources/schema/workflow.json b/api/src/main/resources/schema/workflow.json index 3ed9ce58..dd349995 100644 --- a/api/src/main/resources/schema/workflow.json +++ b/api/src/main/resources/schema/workflow.json @@ -1,5 +1,5 @@ { - "$id": "https://wg-serverless.org/workflow.schema.json", + "$id": "classpath:schema/workflow.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow is a vendor-neutral specification for defining the model of workflows responsible for orchestrating event-driven serverless applications.", "type": "object", diff --git a/pom.xml b/pom.xml index eb36b90f..c9e06c52 100644 --- a/pom.xml +++ b/pom.xml @@ -58,11 +58,10 @@ 2.22.0 3.1.1 2.8.2 - + 1.0.86 1.7.25 - 2.10.3 + 2.15.2 2.0.1.Final - 2.2.14 6.0 5.${version.org.junit.minor} ${version.org.junit} @@ -125,10 +124,16 @@ jackson-databind ${version.com.fasterxml.jackson} - - com.github.java-json-tools - json-schema-validator - ${version.com.github.java-json-tools} + + com.networknt + json-schema-validator + ${version.com.networknt} + + + org.apache.commons + commons-lang3 + + com.fasterxml.jackson.dataformat diff --git a/validation/pom.xml b/validation/pom.xml index c47449a9..6b4e808a 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -34,10 +34,9 @@ org.apache.commons commons-lang3 - - - com.github.java-json-tools - json-schema-validator + + com.networknt + json-schema-validator diff --git a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java index 1e7022f4..783db92e 100644 --- a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java +++ b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java @@ -16,8 +16,8 @@ package io.serverlessworkflow.validation; import com.fasterxml.jackson.databind.JsonNode; -import com.github.fge.jsonschema.core.exceptions.ProcessingException; -import com.github.fge.jsonschema.main.JsonSchemaFactory; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion.VersionFlag; import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.actions.Action; import io.serverlessworkflow.api.events.EventDefinition; @@ -66,11 +66,12 @@ public Collection validate() { validationErrors.clear(); if (workflow == null && schemaValidationEnabled && source != null) { try { - JsonSchemaFactory.byDefault() - .getJsonSchema(workflowSchema) + + JsonSchemaFactory.getInstance(VersionFlag.V202012) + .getSchema(workflowSchema) .validate(Utils.getNode(source)) .forEach(m -> addValidationError(m.getMessage(), ValidationError.SCHEMA_VALIDATION)); - } catch (ProcessingException | IOException e) { + } catch (IOException e) { logger.error("Unexpected error during validation", e); } } @@ -366,7 +367,17 @@ private boolean haveEventsDefinition(String eventName, List eve } } + private static final Set skipMessages = + Set.of( + "$.start: string found, object expected", + "$.functions: array found, object expected", + "$.events: array found, object expected", + "$.retries: array found, object expected"); + private void addValidationError(String message, String type) { + if (skipMessages.contains(message)) { + return; + } ValidationError mainError = new ValidationError(); mainError.setMessage(message); mainError.setType(type); @@ -375,29 +386,9 @@ private void addValidationError(String message, String type) { private class Validation { - final Set events = new HashSet<>(); - final Set functions = new HashSet<>(); final Set states = new HashSet<>(); Integer endStates = 0; - void addFunction(String name) { - if (functions.contains(name)) { - addValidationError( - "Function does not have an unique name: " + name, ValidationError.WORKFLOW_VALIDATION); - } else { - functions.add(name); - } - } - - void addEvent(String name) { - if (events.contains(name)) { - addValidationError( - "Event does not have an unique name: " + name, ValidationError.WORKFLOW_VALIDATION); - } else { - events.add(name); - } - } - void addState(String name) { if (states.contains(name)) { addValidationError( diff --git a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java index 052bc687..72f40a3a 100644 --- a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java +++ b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java @@ -46,7 +46,6 @@ public void testIncompleteYamlWithSchemaValidation() { Collection validationErrors = workflowValidator.setSource("---\n" + "key: abc\n").validate(); Assertions.assertNotNull(validationErrors); - System.out.println(validationErrors); Assertions.assertEquals(3, validationErrors.size()); } @@ -170,14 +169,6 @@ public void testOperationStateNoFunctionRef() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - - Assertions.assertTrue( - validationErrors.stream() - .anyMatch( - v -> - v.getMessage() - .equals( - "Operation State action functionRef does not reference an existing workflow function definition"))); } @Test From 159c15d3ce16fc8aa507544c467a7de7877d2861 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> Date: Mon, 10 Jul 2023 14:50:35 -0300 Subject: [PATCH 03/33] Enable dependabot to upgrade libs (#240) We can rely on GitHub's dependabot to open PRs with version upgrades and CVEs fixes to avoid future problems. Signed-off-by: Ricardo Zanini --- .github/dependabot.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..06541a8b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "maven" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + assignees: + - ricardozanini + - tsurdilo From c2c01228f3032b383cf87f7eb28b22b74158a599 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 7 Jul 2023 11:38:56 +0200 Subject: [PATCH 04/33] Review comments Signed-off-by: Francisco Javier Tirado Sarti Signed-off-by: Ricardo Zanini --- .../validation/WorkflowValidatorImpl.java | 36 ++++-------- .../test/WorkflowValidationTest.java | 56 +++++++++++++++++++ 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java index 783db92e..1aed35ff 100644 --- a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java +++ b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java @@ -64,13 +64,14 @@ public WorkflowValidator setSource(String source) { @Override public Collection validate() { validationErrors.clear(); - if (workflow == null && schemaValidationEnabled && source != null) { + if (workflow == null) { try { - - JsonSchemaFactory.getInstance(VersionFlag.V202012) - .getSchema(workflowSchema) - .validate(Utils.getNode(source)) - .forEach(m -> addValidationError(m.getMessage(), ValidationError.SCHEMA_VALIDATION)); + if (schemaValidationEnabled && source != null) { + JsonSchemaFactory.getInstance(VersionFlag.V7) + .getSchema(workflowSchema) + .validate(Utils.getNode(source)) + .forEach(m -> addValidationError(m.getMessage(), ValidationError.SCHEMA_VALIDATION)); + } } catch (IOException e) { logger.error("Unexpected error during validation", e); } @@ -163,17 +164,6 @@ public Collection validate() { } if (action.getEventRef() != null) { - if (action.getEventRef().getTriggerEventRef().isEmpty()) { - addValidationError( - "Operation State action trigger eventRef does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } - - if (action.getEventRef().getResultEventRef().isEmpty()) { - addValidationError( - "Operation State action results eventRef does not reference an existing workflow event definition", - ValidationError.WORKFLOW_VALIDATION); - } if (!haveEventsDefinition( action.getEventRef().getTriggerEventRef(), events)) { @@ -357,22 +347,19 @@ private boolean haveFunctionDefinition(String functionName, List events) { + if (eventName == null) { + return true; + } if (events != null) { EventDefinition eve = events.stream().filter(e -> e.getName().equals(eventName)).findFirst().orElse(null); - return eve == null ? false : true; } else { return false; } } - private static final Set skipMessages = - Set.of( - "$.start: string found, object expected", - "$.functions: array found, object expected", - "$.events: array found, object expected", - "$.retries: array found, object expected"); + private static final Set skipMessages = Set.of("$.start: string found, object expected"); private void addValidationError(String message, String type) { if (skipMessages.contains(message)) { @@ -385,7 +372,6 @@ private void addValidationError(String message, String type) { } private class Validation { - final Set states = new HashSet<>(); Integer endStates = 0; diff --git a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java index 72f40a3a..b040d101 100644 --- a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java +++ b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java @@ -15,14 +15,26 @@ */ package io.serverlessworkflow.validation.test; +import static io.serverlessworkflow.api.states.DefaultState.Type.OPERATION; import static io.serverlessworkflow.api.states.DefaultState.Type.SLEEP; import io.serverlessworkflow.api.Workflow; +import io.serverlessworkflow.api.actions.Action; import io.serverlessworkflow.api.end.End; +import io.serverlessworkflow.api.events.EventDefinition; +import io.serverlessworkflow.api.events.EventRef; +import io.serverlessworkflow.api.functions.FunctionDefinition; +import io.serverlessworkflow.api.functions.FunctionDefinition.Type; +import io.serverlessworkflow.api.functions.FunctionRef; import io.serverlessworkflow.api.interfaces.WorkflowValidator; +import io.serverlessworkflow.api.retry.RetryDefinition; import io.serverlessworkflow.api.start.Start; +import io.serverlessworkflow.api.states.OperationState; import io.serverlessworkflow.api.states.SleepState; import io.serverlessworkflow.api.validation.ValidationError; +import io.serverlessworkflow.api.workflow.Events; +import io.serverlessworkflow.api.workflow.Functions; +import io.serverlessworkflow.api.workflow.Retries; import io.serverlessworkflow.validation.WorkflowValidatorImpl; import java.util.Arrays; import java.util.Collection; @@ -123,6 +135,50 @@ public void testWorkflowMissingStatesIdAndKey() { 2); } + @Test + void testFunctionCall() { + Workflow workflow = + new Workflow() + .withId("test-workflow") + .withVersion("1.0") + .withStart(new Start().withStateName("start")) + .withFunctions( + new Functions( + Arrays.asList(new FunctionDefinition("expression").withType(Type.EXPRESSION)))) + .withStates( + Arrays.asList( + new OperationState() + .withName("start") + .withType(OPERATION) + .withActions( + Arrays.asList( + new Action().withFunctionRef(new FunctionRef("expression")))) + .withEnd(new End()))); + Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); + } + + @Test + void testEventCall() { + Workflow workflow = + new Workflow() + .withId("test-workflow") + .withVersion("1.0") + .withStart(new Start().withStateName("start")) + .withEvents(new Events(Arrays.asList(new EventDefinition().withName("event")))) + .withRetries(new Retries(Arrays.asList(new RetryDefinition("start", "PT1S")))) + .withStates( + Arrays.asList( + new OperationState() + .withName("start") + .withType(OPERATION) + .withActions( + Arrays.asList( + new Action() + .withEventRef(new EventRef().withTriggerEventRef("event")))) + .withEnd(new End()))); + Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); + } + @Test public void testOperationStateNoFunctionRef() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); From 7891b9f7f643de0e5979287ab9775dce453113d6 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Wed, 12 Jul 2023 18:12:30 +0200 Subject: [PATCH 05/33] Validation Error Test Signed-off-by: Francisco Javier Tirado Sarti Signed-off-by: Ricardo Zanini --- .../api/test/ValidationErrorTest.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java diff --git a/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java b/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java new file mode 100644 index 00000000..34b02799 --- /dev/null +++ b/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.api.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.serverlessworkflow.api.validation.ValidationError; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import org.junit.jupiter.api.Test; + +public class ValidationErrorTest { + + @Test + void duplicateTest() { + + Collection duplicatedErrors = addMessagesToCollection(new ArrayList<>()); + Collection errors = addMessagesToCollection(new LinkedHashSet<>()); + + assertEquals(duplicatedErrors.size(), 3); + assertEquals(errors.size(), 2); + + assertEquals(duplicatedErrors.iterator().next().getMessage(), "This is the first message"); + assertEquals(errors.iterator().next().getMessage(), "This is the first message"); + } + + private Collection addMessagesToCollection(Collection errors) { + ValidationError first = new ValidationError(); + first.setMessage("This is the first message"); + ValidationError second = new ValidationError(); + second.setMessage("This is the duplicated message"); + ValidationError third = new ValidationError(); + third.setMessage("This is the duplicated message"); + errors.add(first); + errors.add(second); + errors.add(third); + return errors; + } +} From fd35a9ed04b8542c146b60ab832ca3afe1345c99 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Thu, 13 Jul 2023 16:01:10 +0200 Subject: [PATCH 06/33] Changing validator back to List Signed-off-by: Francisco Javier Tirado Sarti Signed-off-by: Ricardo Zanini --- .../api/interfaces/WorkflowValidator.java | 4 +- .../api/validation/ValidationError.java | 16 -- .../api/test/ValidationErrorTest.java | 53 ------ .../validation/WorkflowValidatorImpl.java | 10 +- .../test/WorkflowValidationTest.java | 156 ++++++++---------- 5 files changed, 80 insertions(+), 159 deletions(-) delete mode 100644 api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java diff --git a/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java b/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java index 09c79066..199a0927 100644 --- a/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java +++ b/api/src/main/java/io/serverlessworkflow/api/interfaces/WorkflowValidator.java @@ -17,7 +17,7 @@ import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.validation.ValidationError; -import java.util.Collection; +import java.util.List; public interface WorkflowValidator { @@ -25,7 +25,7 @@ public interface WorkflowValidator { WorkflowValidator setSource(String source); - Collection validate(); + List validate(); boolean isValid(); diff --git a/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java b/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java index 2aebccf9..edb92eff 100644 --- a/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java +++ b/api/src/main/java/io/serverlessworkflow/api/validation/ValidationError.java @@ -15,8 +15,6 @@ */ package io.serverlessworkflow.api.validation; -import java.util.Objects; - public class ValidationError { private static final String MSG_FORMAT = "%s:%s"; public static final String SCHEMA_VALIDATION = "schemavalidation"; @@ -45,18 +43,4 @@ public void setType(String type) { public String toString() { return String.format(MSG_FORMAT, type, message); } - - @Override - public int hashCode() { - return Objects.hash(message, type); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - ValidationError other = (ValidationError) obj; - return Objects.equals(message, other.message) && Objects.equals(type, other.type); - } } diff --git a/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java b/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java deleted file mode 100644 index 34b02799..00000000 --- a/api/src/test/java/io/serverlessworkflow/api/test/ValidationErrorTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * 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 io.serverlessworkflow.api.test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.serverlessworkflow.api.validation.ValidationError; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashSet; -import org.junit.jupiter.api.Test; - -public class ValidationErrorTest { - - @Test - void duplicateTest() { - - Collection duplicatedErrors = addMessagesToCollection(new ArrayList<>()); - Collection errors = addMessagesToCollection(new LinkedHashSet<>()); - - assertEquals(duplicatedErrors.size(), 3); - assertEquals(errors.size(), 2); - - assertEquals(duplicatedErrors.iterator().next().getMessage(), "This is the first message"); - assertEquals(errors.iterator().next().getMessage(), "This is the first message"); - } - - private Collection addMessagesToCollection(Collection errors) { - ValidationError first = new ValidationError(); - first.setMessage("This is the first message"); - ValidationError second = new ValidationError(); - second.setMessage("This is the duplicated message"); - ValidationError third = new ValidationError(); - third.setMessage("This is the duplicated message"); - errors.add(first); - errors.add(second); - errors.add(third); - return errors; - } -} diff --git a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java index 1aed35ff..84dbb432 100644 --- a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java +++ b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java @@ -32,9 +32,8 @@ import io.serverlessworkflow.api.validation.ValidationError; import io.serverlessworkflow.api.validation.WorkflowSchemaLoader; import java.io.IOException; -import java.util.Collection; +import java.util.ArrayList; import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.slf4j.Logger; @@ -44,7 +43,7 @@ public class WorkflowValidatorImpl implements WorkflowValidator { private static final Logger logger = LoggerFactory.getLogger(WorkflowValidatorImpl.class); private boolean schemaValidationEnabled = true; - private Collection validationErrors = new LinkedHashSet<>(); + private List validationErrors = new ArrayList<>(); private JsonNode workflowSchema = WorkflowSchemaLoader.getWorkflowSchema(); private String source; private Workflow workflow; @@ -62,7 +61,7 @@ public WorkflowValidator setSource(String source) { } @Override - public Collection validate() { + public List validate() { validationErrors.clear(); if (workflow == null) { try { @@ -359,7 +358,8 @@ private boolean haveEventsDefinition(String eventName, List eve } } - private static final Set skipMessages = Set.of("$.start: string found, object expected"); + private static final Set skipMessages = + Set.of("$.start: string found, object expected", "$.functions: array found, object expected"); private void addValidationError(String message, String type) { if (skipMessages.contains(message)) { diff --git a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java index b040d101..e600e253 100644 --- a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java +++ b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java @@ -37,7 +37,7 @@ import io.serverlessworkflow.api.workflow.Retries; import io.serverlessworkflow.validation.WorkflowValidatorImpl; import java.util.Arrays; -import java.util.Collection; +import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -46,7 +46,7 @@ public class WorkflowValidationTest { @Test public void testIncompleteJsonWithSchemaValidation() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator.setSource("{\n" + " \"id\": \"abc\" \n" + "}").validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(3, validationErrors.size()); @@ -55,7 +55,7 @@ public void testIncompleteJsonWithSchemaValidation() { @Test public void testIncompleteYamlWithSchemaValidation() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator.setSource("---\n" + "key: abc\n").validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(3, validationErrors.size()); @@ -77,22 +77,18 @@ public void testFromIncompleteWorkflow() { .withDuration("PT1M"))); WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = - workflowValidator.setWorkflow(workflow).validate(); + List validationErrors = workflowValidator.setWorkflow(workflow).validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - Assertions.assertTrue( - validationErrors.stream() - .anyMatch( - v -> - v.getMessage() - .equals("No state name found that matches the workflow start definition"))); + Assertions.assertEquals( + "No state name found that matches the workflow start definition", + validationErrors.get(0).getMessage()); } @Test public void testWorkflowMissingStates() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator .setSource( "{\n" @@ -106,14 +102,13 @@ public void testWorkflowMissingStates() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); - Assertions.assertTrue( - validationErrors.stream().anyMatch(v -> v.getMessage().equals("No states found"))); + Assertions.assertEquals("No states found", validationErrors.get(0).getMessage()); } @Test public void testWorkflowMissingStatesIdAndKey() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator .setSource( "{\n" @@ -125,64 +120,16 @@ public void testWorkflowMissingStatesIdAndKey() { .validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(2, validationErrors.size()); - Assertions.assertEquals( - validationErrors.stream() - .filter( - v -> - v.getMessage().equals("No states found") - || v.getMessage().equals("Workflow id or key should not be empty")) - .count(), - 2); - } - - @Test - void testFunctionCall() { - Workflow workflow = - new Workflow() - .withId("test-workflow") - .withVersion("1.0") - .withStart(new Start().withStateName("start")) - .withFunctions( - new Functions( - Arrays.asList(new FunctionDefinition("expression").withType(Type.EXPRESSION)))) - .withStates( - Arrays.asList( - new OperationState() - .withName("start") - .withType(OPERATION) - .withActions( - Arrays.asList( - new Action().withFunctionRef(new FunctionRef("expression")))) - .withEnd(new End()))); - Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); - } - @Test - void testEventCall() { - Workflow workflow = - new Workflow() - .withId("test-workflow") - .withVersion("1.0") - .withStart(new Start().withStateName("start")) - .withEvents(new Events(Arrays.asList(new EventDefinition().withName("event")))) - .withRetries(new Retries(Arrays.asList(new RetryDefinition("start", "PT1S")))) - .withStates( - Arrays.asList( - new OperationState() - .withName("start") - .withType(OPERATION) - .withActions( - Arrays.asList( - new Action() - .withEventRef(new EventRef().withTriggerEventRef("event")))) - .withEnd(new End()))); - Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); + Assertions.assertEquals( + "Workflow id or key should not be empty", validationErrors.get(0).getMessage()); + Assertions.assertEquals("No states found", validationErrors.get(1).getMessage()); } @Test public void testOperationStateNoFunctionRef() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator .setSource( "{\n" @@ -225,6 +172,10 @@ public void testOperationStateNoFunctionRef() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(1, validationErrors.size()); + + Assertions.assertEquals( + "Operation State action functionRef does not reference an existing workflow function definition", + validationErrors.get(0).getMessage()); } @Test @@ -242,8 +193,7 @@ public void testValidateWorkflowForOptionalStartStateAndWorkflowName() { .withDuration("PT1M"))); WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = - workflowValidator.setWorkflow(workflow).validate(); + List validationErrors = workflowValidator.setWorkflow(workflow).validate(); Assertions.assertNotNull(validationErrors); Assertions.assertEquals(0, validationErrors.size()); } @@ -251,7 +201,7 @@ public void testValidateWorkflowForOptionalStartStateAndWorkflowName() { @Test public void testValidateWorkflowForOptionalIterationParam() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator .setSource( "{\n" @@ -292,13 +242,15 @@ public void testValidateWorkflowForOptionalIterationParam() { .validate(); Assertions.assertNotNull(validationErrors); - Assertions.assertEquals(1, validationErrors.size()); + Assertions.assertEquals( + 1, + validationErrors.size()); // validation error raised for functionref not for iterationParam } @Test public void testMissingFunctionRefForCallbackState() { WorkflowValidator workflowValidator = new WorkflowValidatorImpl(); - Collection validationErrors = + List validationErrors = workflowValidator .setSource( "{\n" @@ -332,16 +284,54 @@ public void testMissingFunctionRefForCallbackState() { Assertions.assertNotNull(validationErrors); Assertions.assertEquals(2, validationErrors.size()); Assertions.assertEquals( - validationErrors.stream() - .filter( - v -> - v.getMessage() - .equals( - "CallbackState event ref does not reference a defined workflow event definition") - || v.getMessage() - .equals( - "CallbackState action function ref does not reference a defined workflow function definition")) - .count(), - 2); + "CallbackState event ref does not reference a defined workflow event definition", + validationErrors.get(0).getMessage()); + Assertions.assertEquals( + "CallbackState action function ref does not reference a defined workflow function definition", + validationErrors.get(1).getMessage()); + } + + @Test + void testFunctionCall() { + Workflow workflow = + new Workflow() + .withId("test-workflow") + .withVersion("1.0") + .withStart(new Start().withStateName("start")) + .withFunctions( + new Functions( + Arrays.asList(new FunctionDefinition("expression").withType(Type.EXPRESSION)))) + .withStates( + Arrays.asList( + new OperationState() + .withName("start") + .withType(OPERATION) + .withActions( + Arrays.asList( + new Action().withFunctionRef(new FunctionRef("expression")))) + .withEnd(new End()))); + Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); + } + + @Test + void testEventCall() { + Workflow workflow = + new Workflow() + .withId("test-workflow") + .withVersion("1.0") + .withStart(new Start().withStateName("start")) + .withEvents(new Events(Arrays.asList(new EventDefinition().withName("event")))) + .withRetries(new Retries(Arrays.asList(new RetryDefinition("start", "PT1S")))) + .withStates( + Arrays.asList( + new OperationState() + .withName("start") + .withType(OPERATION) + .withActions( + Arrays.asList( + new Action() + .withEventRef(new EventRef().withTriggerEventRef("event")))) + .withEnd(new End()))); + Assertions.assertTrue(new WorkflowValidatorImpl().setWorkflow(workflow).validate().isEmpty()); } } From 078a930090054d9aff737d99d255ab83d42903bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 14:05:58 +0000 Subject: [PATCH 07/33] Bump org.apache.commons:commons-lang3 from 3.9 to 3.13.0 Bumps org.apache.commons:commons-lang3 from 3.9 to 3.13.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c9e06c52..9504f276 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ 1.4.8 3.13.2 1.0.1 - 3.9 + 3.13.0 1.3 1.5.0 1.14.1 From 6a84c9ef85c97363546adc96759f5754406ebf20 Mon Sep 17 00:00:00 2001 From: Vishesh Ruparelia Date: Sat, 5 Aug 2023 15:01:57 +0530 Subject: [PATCH 08/33] add missing support for contextAttributes in ProduceEvent Signed-off-by: Vishesh Ruparelia Signed-off-by: Ricardo Zanini --- api/src/main/resources/schema/produce/produceevent.json | 5 +++++ .../serverlessworkflow/api/test/MarkupToWorkflowTest.java | 7 +++++++ api/src/test/resources/features/transitions.json | 6 +++++- api/src/test/resources/features/transitions.yml | 3 +++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/api/src/main/resources/schema/produce/produceevent.json b/api/src/main/resources/schema/produce/produceevent.json index b5bb7d5f..f094824e 100644 --- a/api/src/main/resources/schema/produce/produceevent.json +++ b/api/src/main/resources/schema/produce/produceevent.json @@ -10,6 +10,11 @@ "data": { "type": "string", "description": "Workflow expression which selects parts of the states data output to become the data of the produced event" + }, + "contextAttributes": { + "type": "object", + "description": "Add additional event extension context attributes", + "existingJavaType": "java.util.Map" } }, "required": [ diff --git a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java index a1854d43..3c7c7a65 100644 --- a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java @@ -44,6 +44,8 @@ import io.serverlessworkflow.api.workflow.Retries; import io.serverlessworkflow.api.workflow.Secrets; import java.util.List; +import java.util.Map; + import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -264,6 +266,11 @@ public void testTransitions(String workflowLocation) { assertEquals("RejectApplication", cond2.getTransition().getNextState()); assertNotNull(cond2.getTransition().getProduceEvents()); assertEquals(1, cond2.getTransition().getProduceEvents().size()); + assertNotNull(cond2.getTransition().getProduceEvents().get(0).getContextAttributes()); + Map contextAttributes = cond2.getTransition().getProduceEvents().get(0).getContextAttributes(); + assertEquals(2, contextAttributes.size()); + assertEquals("IN", contextAttributes.get("order_location")); + assertEquals("online", contextAttributes.get("order_type")); assertFalse(cond2.getTransition().isCompensate()); assertNotNull(switchState.getDefaultCondition()); diff --git a/api/src/test/resources/features/transitions.json b/api/src/test/resources/features/transitions.json index cacc94af..ed7b7626 100644 --- a/api/src/test/resources/features/transitions.json +++ b/api/src/test/resources/features/transitions.json @@ -23,7 +23,11 @@ "produceEvents": [ { "eventRef": "provisioningCompleteEvent", - "data": "${ .provisionedOrders }" + "data": "${ .provisionedOrders }", + "contextAttributes": { + "order_location": "IN", + "order_type": "online" + } } ] } diff --git a/api/src/test/resources/features/transitions.yml b/api/src/test/resources/features/transitions.yml index 1b89a85f..3ec34ae4 100644 --- a/api/src/test/resources/features/transitions.yml +++ b/api/src/test/resources/features/transitions.yml @@ -18,6 +18,9 @@ states: produceEvents: - eventRef: provisioningCompleteEvent data: "${ .provisionedOrders }" + contextAttributes: + "order_location": "IN" + "order_type": "online" defaultCondition: transition: nextState: RejectApplication From 1133bbbd8307f06ce32cb28d13a9b20cb2afb334 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:14:19 +0000 Subject: [PATCH 09/33] Bump ch.qos.logback:logback-classic from 1.4.8 to 1.4.9 Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.4.8 to 1.4.9. - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.8...v_1.4.9) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9504f276..9d564994 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ 5.${version.org.junit.minor} ${version.org.junit} 3.0.0 - 1.4.8 + 1.4.9 3.13.2 1.0.1 3.13.0 From ac9af39c7a5821ad22741585c813246f727d8de8 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Thu, 28 Sep 2023 11:42:46 -0300 Subject: [PATCH 10/33] Update Code of Conduct to follow the new standard Signed-off-by: Ricardo Zanini --- code-of-conduct.md | 65 +++++++--------------------------------------- 1 file changed, 9 insertions(+), 56 deletions(-) diff --git a/code-of-conduct.md b/code-of-conduct.md index ddd14b6d..97a8526a 100644 --- a/code-of-conduct.md +++ b/code-of-conduct.md @@ -1,58 +1,11 @@ -## CNCF Community Code of Conduct v1.0 +# Code of Conduct -Other languages available: -- [Chinese/中文](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/zh.md) -- [German/Deutsch](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/de.md) -- [Spanish/Español](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/es.md) -- [French/Français](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/fr.md) -- [Italian/Italiano](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/it.md) -- [Japanese/日本語](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/jp.md) -- [Korean/한국어](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ko.md) -- [Ukrainian/Українська](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/uk.md) -- [Russian/Русский](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ru.md) -- [Portuguese/Português](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/pt.md) -- [Arabic/العربية](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ar.md) -- [Polish/Polski](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/pl.md) +We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). -### Contributor Code of Conduct - -As contributors and maintainers of this project, and in the interest of fostering -an open and welcoming community, we pledge to respect all people who contribute -through reporting issues, posting feature requests, updating documentation, -submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free experience for -everyone, regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, body size, race, ethnicity, age, -religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing others' private information, such as physical or electronic addresses, - without explicit permission -* Other unethical or unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are not -aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers -commit themselves to fairly and consistently applying these principles to every aspect -of managing this project. Project maintainers who do not follow or enforce the Code of -Conduct may be permanently removed from the project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior in Kubernetes may be reported by contacting the [Kubernetes Code of Conduct Committee](https://git.k8s.io/community/committee-code-of-conduct) via conduct@kubernetes.io. For other projects, please contact a CNCF project maintainer or our mediator, Mishi Choudhary via mishi@linux.com. - -This Code of Conduct is adapted from the Contributor Covenant -(), version 1.2.0, available at - - -### CNCF Events Code of Conduct - -CNCF events are governed by the Linux Foundation [Code of Conduct](https://events.linuxfoundation.org/code-of-conduct/) available on the event page. -This is designed to be compatible with the above policy and also includes more details on responding to incidents. \ No newline at end of file + +Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) +in order to report violations of the Code of Conduct. From 7ca919ec8ea1f78ba1416b509b8f7d2cc93b81f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:16:48 +0000 Subject: [PATCH 11/33] Bump org.thymeleaf:thymeleaf from 3.0.11.RELEASE to 3.1.2.RELEASE Bumps org.thymeleaf:thymeleaf from 3.0.11.RELEASE to 3.1.2.RELEASE. --- updated-dependencies: - dependency-name: org.thymeleaf:thymeleaf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d564994..00cb57d2 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ 1.3 1.5.0 1.14.1 - 3.0.11.RELEASE + 3.1.2.RELEASE 8059 0.17.0 2.9 From b2cbb096244ac00d8cb8d6075d55e83af2df23e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:13:47 +0000 Subject: [PATCH 12/33] Bump com.networknt:json-schema-validator from 1.0.86 to 1.0.87 Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.86 to 1.0.87. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.86...1.0.87) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 00cb57d2..202bb58a 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 2.22.0 3.1.1 2.8.2 - 1.0.86 + 1.0.87 1.7.25 2.15.2 2.0.1.Final From d14eac4776689985dfceff4eb5456615d60b301e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:13:53 +0000 Subject: [PATCH 13/33] Bump org.mockito:mockito-core from 3.0.0 to 5.6.0 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 3.0.0 to 5.6.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.0.0...v5.6.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 202bb58a..52d4e46b 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ 6.0 5.${version.org.junit.minor} ${version.org.junit} - 3.0.0 + 5.6.0 1.4.9 3.13.2 1.0.1 From 5a8b6f334824c878e9fba069dda49e1f85f5ebbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:13:58 +0000 Subject: [PATCH 14/33] Bump com.coveo:fmt-maven-plugin from 2.9 to 2.13 Bumps [com.coveo:fmt-maven-plugin](https://github.com/coveooss/fmt-maven-plugin) from 2.9 to 2.13. - [Release notes](https://github.com/coveooss/fmt-maven-plugin/releases) - [Commits](https://github.com/coveooss/fmt-maven-plugin/compare/2.9.0...2.13.0) --- updated-dependencies: - dependency-name: com.coveo:fmt-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52d4e46b..55e03fbd 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 3.1.2.RELEASE 8059 0.17.0 - 2.9 + 2.13 3.2.0 true From 2fc7d7fdc925f8ee5e2329c8715b80acd7ff4ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:14:07 +0000 Subject: [PATCH 15/33] Bump version.com.fasterxml.jackson from 2.15.2 to 2.15.3 Bumps `version.com.fasterxml.jackson` from 2.15.2 to 2.15.3. Updates `com.fasterxml.jackson.core:jackson-core` from 2.15.2 to 2.15.3 - [Release notes](https://github.com/FasterXML/jackson-core/releases) - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.15.2...jackson-core-2.15.3) Updates `com.fasterxml.jackson.core:jackson-databind` from 2.15.2 to 2.15.3 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` from 2.15.2 to 2.15.3 - [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.15.2...jackson-dataformats-text-2.15.3) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55e03fbd..4974165d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.8.2 1.0.87 1.7.25 - 2.15.2 + 2.15.3 2.0.1.Final 6.0 5.${version.org.junit.minor} From e237470eb99be35ac19e41ba1e7a6feef8df6577 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:14:12 +0000 Subject: [PATCH 16/33] Bump org.apache.maven.plugins:maven-failsafe-plugin from 2.22.0 to 3.1.2 Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 2.22.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4974165d..578c217d 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 8 3.8.1 2.22.0 - 2.22.0 + 3.1.2 3.1.1 2.8.2 1.0.87 From f849d182ded2aa0f1c5d23ffdc9e3d3db772512d Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 28 Jul 2023 12:22:20 -0300 Subject: [PATCH 17/33] Introduce Release Workflow Signed-off-by: Ricardo Zanini --- .github/project.yml | 3 + .github/workflows/maven-deploy.yml | 2 +- .github/workflows/maven-verify.yml | 2 +- .github/workflows/pre-release.yml | 25 + .github/workflows/release.yml | 71 +++ pom.xml | 812 +++++++++++++++++------------ 6 files changed, 572 insertions(+), 343 deletions(-) create mode 100644 .github/project.yml create mode 100644 .github/workflows/pre-release.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/project.yml b/.github/project.yml new file mode 100644 index 00000000..f4275350 --- /dev/null +++ b/.github/project.yml @@ -0,0 +1,3 @@ +release: + current-version: 5.0.0 + next-version: 6.0.0-SNAPSHOT \ No newline at end of file diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml index 67812473..f89bf3a0 100644 --- a/.github/workflows/maven-deploy.yml +++ b/.github/workflows/maven-deploy.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Deploy JAVA SDK +name: Deploy SNAPSHOT on: push: diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index 5da52578..db64ea66 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Verify JAVA SDK +name: Verify SNAPSHOT on: push: diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml new file mode 100644 index 00000000..ce904c75 --- /dev/null +++ b/.github/workflows/pre-release.yml @@ -0,0 +1,25 @@ +name: sdk-java Pre Release + +on: + pull_request: + paths: + - '.github/project.yml' + +jobs: + release: + runs-on: ubuntu-latest + name: pre release + + steps: + - uses: radcortez/project-metadata-action@master + name: retrieve project metadata + id: metadata + with: + github-token: ${{secrets.GITHUB_TOKEN}} + metadata-file-path: '.github/project.yml' + + - name: Validate version + if: contains(steps.metadata.outputs.current-version, 'SNAPSHOT') + run: | + echo '::error::Cannot release a SNAPSHOT version.' + exit 1 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..9e683cda --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,71 @@ +name: sdk-java Release + +on: + pull_request: + types: [closed] + paths: + - '.github/project.yml' + +jobs: + release: + runs-on: ubuntu-latest + name: release + if: ${{github.event.pull_request.merged == true}} + + steps: + - uses: radcortez/project-metadata-action@main + name: Retrieve project metadata + id: metadata + with: + github-token: ${{secrets.GITHUB_TOKEN}} + metadata-file-path: '.github/project.yml' + + - uses: actions/checkout@v3 + + - name: Import GPG key + id: import_gpg + uses: crazy-max/ghaction-import-gpg@v5 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 11 + + - name: Cache local Maven repository + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + - name: Configure Git author + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + + - name: Maven release ${{steps.metadata.outputs.current-version}} + run: | + gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.GPG_PASSPHRASE}}" --output /tmp/maven-settings.xml .github/release/maven-settings.xml.gpg + git checkout -b release + mvn -B release:prepare -Prelease -DreleaseVersion=${{steps.metadata.outputs.current-version}} -DdevelopmentVersion=${{steps.metadata.outputs.next-version}} -s /tmp/maven-settings.xml + git checkout ${{github.base_ref}} + git rebase release + mvn -B release:perform -Darguments=-DperformRelease -DperformRelease -Prelease -s /tmp/maven-settings.xml + + - name: Push changes to ${{github.base_ref}} + uses: ad-m/github-push-action@v0.6.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{github.base_ref}} + + - name: Push tags + uses: ad-m/github-push-action@v0.6.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + tags: true + branch: ${{github.base_ref}} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 578c217d..713cc53b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,86 +1,99 @@ - - 4.0.0 + + 4.0.0 - io.serverlessworkflow - serverlessworkflow-parent - 4.0.x - pom + io.serverlessworkflow + serverlessworkflow-parent + 4.0.x + pom - Serverless Workflow :: Parent - https://serverlessworkflow.io/sdk-java/ - Java SDK for Serverless Workflow Specification - 2020 - - CNCF - https://www.cncf.io// - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - + Serverless Workflow :: Parent + https://serverlessworkflow.io/sdk-java/ + Java SDK for Serverless Workflow Specification + 2020 + + + serverless-workflow + Serverless Workflow Specification Authors + CNCF + + + + CNCF + https://www.cncf.io// + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + scm:git:git@github.com:serverlessworkflow/sdk-java.git + scm:git:git@github.com:serverlessworkflow/sdk-java.git + https://github.com/serverlessworkflow/sdk-java + HEAD + - - scm:git:git://github.com/serverlessworkflow/sdk-java.git - scm:git:git@github.com:serverlessworkflow/sdk-java.git - https://github.com/serverlessworkflow/sdk-java - + + api + spi + validation + diagram + utils + - - - tsurdilo - Tihomir Surdilovic - - + + 11 + ${java.version} + ${java.version} + UTF-8 + 3.6.2 - - api - spi - validation - diagram - utils - + + 3.2.0 + 3.1.1 + 3.8.1 + 2.8.2 + 3.0.0-M2 + 3.1.2 + 2.13 + 3.1.0 + 3.2.0 + ${java.version} + 3.3.0 + 2.22.0 - - 1.8 - 1.8 - 1.8 - UTF-8 - 3.6.2 - 3.0.0-M2 - 8 - 3.8.1 - 2.22.0 - 3.1.2 - 3.1.1 - 2.8.2 - 1.0.87 - 1.7.25 - 2.15.3 - 2.0.1.Final - 6.0 - 5.${version.org.junit.minor} - ${version.org.junit} - 5.6.0 - 1.4.9 - 3.13.2 - 1.0.1 - 3.13.0 - 1.3 - 1.5.0 - 1.14.1 - 3.1.2.RELEASE - 8059 - 0.17.0 - 2.13 - 3.2.0 - - true - + 1.4.9 + 2.15.3 + 1.0.87 + 3.13.0 + 0.17.0 + 1.3 + 2.0.1.Final + 1.14.1 + 20230618 + 1.5.0 + 1.0.1 + 3.13.2 + ${version.org.junit} + 6.0 + 5.${version.org.junit.minor} + 5.6.0 + 1.7.25 + 8059 + 3.1.2.RELEASE + + + + true + >>>>>> fdc9b5f (Introduce Release Workflow) ^\/\*$\n^ \* Copyright \d\d\d\d-Present The Serverless Workflow Specification Authors$\n^ \*$\n^ @@ -97,275 +110,392 @@ \* limitations under the License\.$\n^ \*\/$ ]]> - - java - true - + + java + true + + + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + + + org.slf4j + jcl-over-slf4j + ${version.org.slf4j} + + + com.fasterxml.jackson.core + jackson-core + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.core + jackson-databind + ${version.com.fasterxml.jackson} + + + com.networknt + json-schema-validator + ${version.com.networknt} + + + org.apache.commons + commons-lang3 + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${version.com.fasterxml.jackson} + + + javax.validation + validation-api + ${version.javax.validation} + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + org.thymeleaf + thymeleaf + ${version.thymeleaf} + + + net.sourceforge.plantuml + plantuml + ${version.plantuml} + + + guru.nidi + graphviz-java + ${version.graphviz} + + + + + org.junit.jupiter + junit-jupiter-api + ${version.org.junit.jupiter} + test + + + org.junit.jupiter + junit-jupiter-engine + ${version.org.junit.jupiter} + test + + + org.junit.jupiter + junit-jupiter-params + ${version.org.junit.jupiter} + test + + + org.mockito + mockito-core + ${version.org.mockito} + test + + + ch.qos.logback + logback-classic + ${version.ch.qos.logback} + test + + + org.assertj + assertj-core + ${version.org.assertj} + test + + + org.hamcrest + hamcrest-library + ${version.hamcrest} + test + + + org.skyscreamer + jsonassert + ${version.jsonassert} + test + + + - - - - org.slf4j - slf4j-api - ${version.org.slf4j} - - - org.slf4j - jcl-over-slf4j - ${version.org.slf4j} - - - com.fasterxml.jackson.core - jackson-core - ${version.com.fasterxml.jackson} - - - com.fasterxml.jackson.core - jackson-databind - ${version.com.fasterxml.jackson} - - - com.networknt - json-schema-validator - ${version.com.networknt} - - - org.apache.commons - commons-lang3 - - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - ${version.com.fasterxml.jackson} - - - javax.validation - validation-api - ${version.javax.validation} - - - org.apache.commons - commons-lang3 - ${commons.lang.version} - - - org.thymeleaf - thymeleaf - ${version.thymeleaf} - - - net.sourceforge.plantuml - plantuml - ${version.plantuml} - - - guru.nidi - graphviz-java - ${version.graphviz} - + + + + + org.codehaus.mojo + buildnumber-maven-plugin + ${version.buildnumber.plugin} + + + get-scm-revision + initialize + + create + + + false + false + UNKNOWN + true + + + + + + maven-compiler-plugin + ${version.compiler.plugin} + + true + true + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.source} + ${maven.compiler.target} + true + + -Xlint:unchecked + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + - - - org.junit.jupiter - junit-jupiter-api - ${version.org.junit.jupiter} - test - - - org.junit.jupiter - junit-jupiter-engine - ${version.org.junit.jupiter} - test - - - org.junit.jupiter - junit-jupiter-params - ${version.org.junit.jupiter} - test - - - org.mockito - mockito-core - ${version.org.mockito} - test - - - ch.qos.logback - logback-classic - ${version.ch.qos.logback} - test - - - org.assertj - assertj-core - ${version.org.assertj} - test - - - org.hamcrest - hamcrest-library - ${hamcrest.version} - test - - - org.skyscreamer - jsonassert - ${jsonassert.version} - test - - - + + + + org.apache.maven.plugins + maven-gpg-plugin + ${version.gpg.plugin} + + + maven-deploy-plugin + ${version.deploy.plugin} + + 10 + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${version.enforcer.plugin} + + + enforce-versions + + enforce + + + + + ${version.maven} + + + ${version.jdk} + + + + + + + + org.apache.maven.plugins + maven-source-plugin + ${version.source.plugin} + + + true + + + true + + + true + + + + ${project.url} + ${java.version} + ${java.vendor} + ${os.name} + ${os.arch} + ${os.version} + ${project.scm.url} + ${project.scm.connection} + ${buildNumber} + + + + + + org.apache.maven.plugins + maven-release-plugin + ${version.release.plugin} + + clean install + true + @{project.version} + false + true + false + + + + org.jsonschema2pojo + jsonschema2pojo-maven-plugin + ${version.jsonschema2pojo-maven-plugin} + + + org.apache.maven.plugins + maven-surefire-plugin + ${version.surefire.plugin} + + -Xmx1024m -XX:+IgnoreUnrecognizedVMOptions -XX:MaxPermSize=256m + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${version.failsafe.plugin} + + -Xmx1024m -XX:+IgnoreUnrecognizedVMOptions -XX:MaxPermSize=256m + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${version.checkstyle.plugin} + + + com.coveo + fmt-maven-plugin + ${version.fmt-maven-plugin} + + + org.apache.maven.plugins + maven-jar-plugin + ${version.jar.plugin} + + + true + + + true + + + true + + + + ${project.url} + ${java.version} + ${java.vendor} + ${os.name} + ${os.arch} + ${os.version} + ${project.scm.url} + ${project.scm.connection} + ${buildNumber} + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.javadoc.plugin} + + + + - + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + central + Central Repository + https://repo.maven.apache.org/maven2 + default + + false + + + + + + + release + - - maven-deploy-plugin - ${version.deploy.plugin} - - 10 - - - - org.apache.maven.plugins - maven-enforcer-plugin - ${version.enforcer.plugin} - - - enforce-versions - - enforce - - - - - ${version.maven} - - - ${version.jdk} - - - - - - - - maven-compiler-plugin - ${version.compiler.plugin} - - true - true - - -Xlint:unchecked - - - - - org.jsonschema2pojo - jsonschema2pojo-maven-plugin - ${version.jsonschema2pojo-maven-plugin} - - - org.apache.maven.plugins - maven-surefire-plugin - ${version.surefire.plugin} - - -Xmx1024m -XX:+IgnoreUnrecognizedVMOptions -XX:MaxPermSize=256m - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${version.checkstyle.plugin} - - - com.coveo - fmt-maven-plugin - ${version.fmt-maven-plugin} - - - org.apache.maven.plugins - maven-jar-plugin - ${version.jar.plugin} - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.5.0 - - 8 - -Xdoclint:none - - - - attach-javadocs - - jar - - - false - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - --batch - --pinentry-mode - loopback - - - - - + + org.apache.maven.plugins + maven-gpg-plugin + + + --pinentry-mode + loopback + + + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + package + + jar + + + + - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + + + - - - central - Central Repository - https://repo.maven.apache.org/maven2 - default - - false - - - \ No newline at end of file From 24c6569e90b2613f21ea47c5676a55f38a66ea43 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 28 Jul 2023 13:00:50 -0300 Subject: [PATCH 18/33] Remove gpg, deploy workflow Signed-off-by: Ricardo Zanini --- .github/workflows/maven-deploy.yml | 26 ----------------- .github/workflows/maven-verify.yml | 12 +++----- .github/workflows/release.yml | 46 +++++++++++++----------------- pom.xml | 21 ++++++-------- 4 files changed, 32 insertions(+), 73 deletions(-) delete mode 100644 .github/workflows/maven-deploy.yml diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml deleted file mode 100644 index f89bf3a0..00000000 --- a/.github/workflows/maven-deploy.yml +++ /dev/null @@ -1,26 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Deploy SNAPSHOT - -on: - push: - branches: - - main -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Maven Central Repository - uses: actions/setup-java@v1 - with: - java-version: 1.8 - server-id: ossrh - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - - name: Publish package - run: mvn -B -f pom.xml deploy - env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index db64ea66..420e2eb3 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Verify SNAPSHOT +name: Maven Verify on: push: @@ -16,15 +16,11 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: temurin java-version: 1.8 - - name: Cache Maven packages - uses: actions/cache@v2 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + cache: 'maven' - name: Verify with Maven run: | mvn -B -f pom.xml clean install verify diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9e683cda..c417311f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,13 @@ on: types: [closed] paths: - '.github/project.yml' + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + defaults: + run: + shell: bash jobs: release: @@ -34,14 +41,10 @@ jobs: with: distribution: temurin java-version: 11 - - - name: Cache local Maven repository - uses: actions/cache@v3 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- + cache: 'maven' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD - name: Configure Git author run: | @@ -50,22 +53,13 @@ jobs: - name: Maven release ${{steps.metadata.outputs.current-version}} run: | - gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.GPG_PASSPHRASE}}" --output /tmp/maven-settings.xml .github/release/maven-settings.xml.gpg - git checkout -b release - mvn -B release:prepare -Prelease -DreleaseVersion=${{steps.metadata.outputs.current-version}} -DdevelopmentVersion=${{steps.metadata.outputs.next-version}} -s /tmp/maven-settings.xml - git checkout ${{github.base_ref}} - git rebase release - mvn -B release:perform -Darguments=-DperformRelease -DperformRelease -Prelease -s /tmp/maven-settings.xml + mvn -B release:prepare -Prelease -DreleaseVersion=${{steps.metadata.outputs.current-version}} -DdevelopmentVersion=${{steps.metadata.outputs.next-version}} + mvn -B release:perform -Darguments=-DperformRelease -DperformRelease -Prelease + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - - name: Push changes to ${{github.base_ref}} - uses: ad-m/github-push-action@v0.6.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: ${{github.base_ref}} - - - name: Push tags - uses: ad-m/github-push-action@v0.6.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - tags: true - branch: ${{github.base_ref}} \ No newline at end of file + - name: Push changes to ${{github.base_ref}} branch + run: | + git push + git push origin ${{steps.metadata.outputs.current-version}} diff --git a/pom.xml b/pom.xml index 713cc53b..3042340e 100644 --- a/pom.xml +++ b/pom.xml @@ -270,19 +270,6 @@ - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar-no-fork - - - - @@ -326,6 +313,14 @@ org.apache.maven.plugins maven-source-plugin ${version.source.plugin} + + + attach-sources + + jar-no-fork + + + true From 873033bad0043db3841eb135bdd87d3fc4fa2d44 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 28 Jul 2023 13:06:54 -0300 Subject: [PATCH 19/33] formatting yml files Signed-off-by: Ricardo Zanini --- .github/workflows/maven-verify.yml | 24 +++++++++++++----------- .github/workflows/release.yml | 3 --- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index 420e2eb3..37d6d5e7 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Maven Verify +name: sdk-java Verify on: push: @@ -14,13 +14,15 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 1.8 - cache: 'maven' - - name: Verify with Maven - run: | - mvn -B -f pom.xml clean install verify + - uses: actions/checkout@v2 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 1.8 + cache: 'maven' + + - name: Verify with Maven + run: | + mvn -B -f pom.xml clean install verify diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c417311f..22267f17 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,9 +5,6 @@ on: types: [closed] paths: - '.github/project.yml' - concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true defaults: run: From 9df57023210508a168d3289929c0752a0dc4e768 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 28 Jul 2023 13:07:36 -0300 Subject: [PATCH 20/33] Remove unneeded attrs Signed-off-by: Ricardo Zanini --- .github/workflows/release.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22267f17..3d9d4f03 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,10 +6,6 @@ on: paths: - '.github/project.yml' - defaults: - run: - shell: bash - jobs: release: runs-on: ubuntu-latest From 12db91479347c8c2ab79bf54ecd67007e7b6100f Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Wed, 11 Oct 2023 14:59:17 -0300 Subject: [PATCH 21/33] Fix commons-lang3 property version Signed-off-by: Ricardo Zanini --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3042340e..e6edd5f5 100644 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ org.apache.commons commons-lang3 - ${commons.lang.version} + ${version.commons.lang} org.thymeleaf From d85b198796afd8336dcd97cdf71a892287658df8 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Wed, 11 Oct 2023 15:25:46 -0300 Subject: [PATCH 22/33] Removing unused property versions Signed-off-by: Ricardo Zanini --- pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e6edd5f5..244ed807 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ 3.1.0 3.2.0 ${java.version} + 1.0.1 3.3.0 2.22.0 @@ -76,10 +77,7 @@ 0.17.0 1.3 2.0.1.Final - 1.14.1 - 20230618 1.5.0 - 1.0.1 3.13.2 ${version.org.junit} 6.0 From 8483f17fb5760a4622f5d6ba37ebabdd3091f0f6 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Thu, 19 Oct 2023 11:54:00 -0300 Subject: [PATCH 23/33] Fix formatting, replace fmt for spotify group, rebase Signed-off-by: Ricardo Zanini --- api/pom.xml | 2 +- .../api/test/MarkupToWorkflowTest.java | 4 ++-- diagram/pom.xml | 2 +- pom.xml | 4 ++-- spi/pom.xml | 2 +- utils/pom.xml | 2 +- .../utils/WorkflowUtils.java | 20 ++++++++++++++----- validation/pom.xml | 2 +- 8 files changed, 24 insertions(+), 14 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 63ba1ef1..0a7293dc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -143,7 +143,7 @@ - com.coveo + com.spotify.fmt fmt-maven-plugin src/main/java diff --git a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java index 3c7c7a65..f5b30d07 100644 --- a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java @@ -45,7 +45,6 @@ import io.serverlessworkflow.api.workflow.Secrets; import java.util.List; import java.util.Map; - import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -267,7 +266,8 @@ public void testTransitions(String workflowLocation) { assertNotNull(cond2.getTransition().getProduceEvents()); assertEquals(1, cond2.getTransition().getProduceEvents().size()); assertNotNull(cond2.getTransition().getProduceEvents().get(0).getContextAttributes()); - Map contextAttributes = cond2.getTransition().getProduceEvents().get(0).getContextAttributes(); + Map contextAttributes = + cond2.getTransition().getProduceEvents().get(0).getContextAttributes(); assertEquals(2, contextAttributes.size()); assertEquals("IN", contextAttributes.get("order_location")); assertEquals("online", contextAttributes.get("order_type")); diff --git a/diagram/pom.xml b/diagram/pom.xml index 2668c850..9dd5c1b8 100644 --- a/diagram/pom.xml +++ b/diagram/pom.xml @@ -130,7 +130,7 @@ - com.coveo + com.spotify.fmt fmt-maven-plugin src/main/java diff --git a/pom.xml b/pom.xml index 244ed807..0bef666d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.8.2 3.0.0-M2 3.1.2 - 2.13 + 2.21.1 3.1.0 3.2.0 ${java.version} @@ -384,7 +384,7 @@ ${version.checkstyle.plugin} - com.coveo + com.spotify.fmt fmt-maven-plugin ${version.fmt-maven-plugin} diff --git a/spi/pom.xml b/spi/pom.xml index db4fbf79..6fad0bb4 100644 --- a/spi/pom.xml +++ b/spi/pom.xml @@ -102,7 +102,7 @@ - com.coveo + com.spotify.fmt fmt-maven-plugin src/main/java diff --git a/utils/pom.xml b/utils/pom.xml index 3c479281..834e8815 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -102,7 +102,7 @@ - com.coveo + com.spotify.fmt fmt-maven-plugin src/main/java diff --git a/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java b/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java index 29b8c7cc..48340a9f 100644 --- a/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java +++ b/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java @@ -117,18 +117,24 @@ public static List getDefinedEvents( .collect(Collectors.toList()); } - /** @return {@code int} Returns count of defined event count matching eventKind */ + /** + * @return {@code int} Returns count of defined event count matching eventKind + */ public static int getDefinedEventsCount(Workflow workflow, EventDefinition.Kind eventKind) { List definedEvents = getDefinedEvents(workflow, eventKind); return definedEvents == null ? 0 : definedEvents.size(); } - /** @return {@code int} Returns count of Defined Consumed Event Count */ + /** + * @return {@code int} Returns count of Defined Consumed Event Count + */ public static int getDefinedConsumedEventsCount(Workflow workflow) { return getDefinedEventsCount(workflow, EventDefinition.Kind.CONSUMED); } - /** @return {@code int} Returns count of Defined Produced Event Count */ + /** + * @return {@code int} Returns count of Defined Produced Event Count + */ public static int getDefinedProducedEventsCount(Workflow workflow) { return getDefinedEventsCount(workflow, EventDefinition.Kind.PRODUCED); } @@ -252,7 +258,9 @@ public static int getWorkflowProducedEventsCount(Workflow workflow) { return workflowProducedEvents == null ? 0 : workflowProducedEvents.size(); } - /** @return Returns function definition for actions */ + /** + * @return Returns function definition for actions + */ public static FunctionDefinition getFunctionDefinitionsForAction( Workflow workflow, String action) { if (!hasFunctionDefs(workflow)) return null; @@ -267,7 +275,9 @@ public static FunctionDefinition getFunctionDefinitionsForAction( return functionDefinition.isPresent() ? functionDefinition.get() : null; } - /** @return : Returns @{code List} which uses a function defintion */ + /** + * @return : Returns @{code List} which uses a function defintion + */ public static List getActionsForFunctionDefinition( Workflow workflow, String functionDefinitionName) { if (!hasFunctionDefs(workflow, functionDefinitionName)) return null; diff --git a/validation/pom.xml b/validation/pom.xml index 6b4e808a..cf8544e6 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -124,7 +124,7 @@ - com.coveo + com.spotify.fmt fmt-maven-plugin src/main/java From b332fc8752f05be82af1b0e5b93c45f25a737a39 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 10:54:27 -0300 Subject: [PATCH 24/33] Sync main with 4.0.x Signed-off-by: Ricardo Zanini --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0bef666d..df7bab94 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,6 @@ true >>>>>> fdc9b5f (Introduce Release Workflow) ^\/\*$\n^ \* Copyright \d\d\d\d-Present The Serverless Workflow Specification Authors$\n^ \*$\n^ From 67a66346da87aeca7dd9f90fb53d25a2a7a31e1f Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 10:55:10 -0300 Subject: [PATCH 25/33] Downgrade to Java 1.8 Signed-off-by: Ricardo Zanini --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d9d4f03..a2cda762 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,11 +29,11 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} - - name: Set up JDK 11 + - name: Set up JDK 1.8 uses: actions/setup-java@v3 with: distribution: temurin - java-version: 11 + java-version: 1.8 cache: 'maven' server-id: ossrh server-username: MAVEN_USERNAME From 4431edda1392f413f3d75a1c2c0b632e1a003173 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:01:36 -0300 Subject: [PATCH 26/33] Align workflow to run on 4.0.* branch Signed-off-by: Ricardo Zanini --- .github/workflows/maven-verify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index 37d6d5e7..e7b3b0ce 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -6,10 +6,10 @@ name: sdk-java Verify on: push: branches: - - main + - 4.0.* pull_request: branches: - - main + - 4.0.* jobs: build: runs-on: ubuntu-latest From 432a7a12beeb5d57aa7712492a8d6a13eb6fd3b8 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:06:06 -0300 Subject: [PATCH 27/33] Fix java version in setup-java action Signed-off-by: Ricardo Zanini --- .github/workflows/maven-verify.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index e7b3b0ce..44aba632 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -20,7 +20,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: temurin - java-version: 1.8 + java-version: 8 cache: 'maven' - name: Verify with Maven diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2cda762..f2341c8a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: temurin - java-version: 1.8 + java-version: 8 cache: 'maven' server-id: ossrh server-username: MAVEN_USERNAME From 7a9d0b3a8f9006ea801d57d578285f64151ba814 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:19:02 -0300 Subject: [PATCH 28/33] Downgrading fmt plugin to cope with Java 1.8 Signed-off-by: Ricardo Zanini --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index df7bab94..625c99ab 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ - 11 + 1.8 ${java.version} ${java.version} UTF-8 @@ -60,7 +60,7 @@ 2.8.2 3.0.0-M2 3.1.2 - 2.21.1 + 2.9 3.1.0 3.2.0 ${java.version} @@ -383,7 +383,7 @@ ${version.checkstyle.plugin} - com.spotify.fmt + com.coveo fmt-maven-plugin ${version.fmt-maven-plugin} From b4a187a477e4917d44a1871d8424a7606c2f27da Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:25:10 -0300 Subject: [PATCH 29/33] Fix fmt downgrading Signed-off-by: Ricardo Zanini --- api/pom.xml | 2 +- diagram/pom.xml | 2 +- pom.xml | 2 +- spi/pom.xml | 2 +- utils/pom.xml | 2 +- .../utils/WorkflowUtils.java | 20 +++++-------------- validation/pom.xml | 2 +- 7 files changed, 11 insertions(+), 21 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 0a7293dc..63ba1ef1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -143,7 +143,7 @@ - com.spotify.fmt + com.coveo fmt-maven-plugin src/main/java diff --git a/diagram/pom.xml b/diagram/pom.xml index 9dd5c1b8..2668c850 100644 --- a/diagram/pom.xml +++ b/diagram/pom.xml @@ -130,7 +130,7 @@ - com.spotify.fmt + com.coveo fmt-maven-plugin src/main/java diff --git a/pom.xml b/pom.xml index 625c99ab..22486415 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.8.2 3.0.0-M2 3.1.2 - 2.9 + 2.9.1 3.1.0 3.2.0 ${java.version} diff --git a/spi/pom.xml b/spi/pom.xml index 6fad0bb4..db4fbf79 100644 --- a/spi/pom.xml +++ b/spi/pom.xml @@ -102,7 +102,7 @@ - com.spotify.fmt + com.coveo fmt-maven-plugin src/main/java diff --git a/utils/pom.xml b/utils/pom.xml index 834e8815..3c479281 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -102,7 +102,7 @@ - com.spotify.fmt + com.coveo fmt-maven-plugin src/main/java diff --git a/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java b/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java index 48340a9f..29b8c7cc 100644 --- a/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java +++ b/utils/src/main/java/io/serverlessworkflow/utils/WorkflowUtils.java @@ -117,24 +117,18 @@ public static List getDefinedEvents( .collect(Collectors.toList()); } - /** - * @return {@code int} Returns count of defined event count matching eventKind - */ + /** @return {@code int} Returns count of defined event count matching eventKind */ public static int getDefinedEventsCount(Workflow workflow, EventDefinition.Kind eventKind) { List definedEvents = getDefinedEvents(workflow, eventKind); return definedEvents == null ? 0 : definedEvents.size(); } - /** - * @return {@code int} Returns count of Defined Consumed Event Count - */ + /** @return {@code int} Returns count of Defined Consumed Event Count */ public static int getDefinedConsumedEventsCount(Workflow workflow) { return getDefinedEventsCount(workflow, EventDefinition.Kind.CONSUMED); } - /** - * @return {@code int} Returns count of Defined Produced Event Count - */ + /** @return {@code int} Returns count of Defined Produced Event Count */ public static int getDefinedProducedEventsCount(Workflow workflow) { return getDefinedEventsCount(workflow, EventDefinition.Kind.PRODUCED); } @@ -258,9 +252,7 @@ public static int getWorkflowProducedEventsCount(Workflow workflow) { return workflowProducedEvents == null ? 0 : workflowProducedEvents.size(); } - /** - * @return Returns function definition for actions - */ + /** @return Returns function definition for actions */ public static FunctionDefinition getFunctionDefinitionsForAction( Workflow workflow, String action) { if (!hasFunctionDefs(workflow)) return null; @@ -275,9 +267,7 @@ public static FunctionDefinition getFunctionDefinitionsForAction( return functionDefinition.isPresent() ? functionDefinition.get() : null; } - /** - * @return : Returns @{code List} which uses a function defintion - */ + /** @return : Returns @{code List} which uses a function defintion */ public static List getActionsForFunctionDefinition( Workflow workflow, String functionDefinitionName) { if (!hasFunctionDefs(workflow, functionDefinitionName)) return null; diff --git a/validation/pom.xml b/validation/pom.xml index cf8544e6..6b4e808a 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -124,7 +124,7 @@ - com.spotify.fmt + com.coveo fmt-maven-plugin src/main/java From 271cc0bd4e2d2a7564f5231485e41ddffe231bc1 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:30:58 -0300 Subject: [PATCH 30/33] Change WorkflowValidatorImpl to match Java 8 API Signed-off-by: Ricardo Zanini --- .../validation/WorkflowValidatorImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java index 84dbb432..12e4e915 100644 --- a/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java +++ b/validation/src/main/java/io/serverlessworkflow/validation/WorkflowValidatorImpl.java @@ -359,7 +359,12 @@ private boolean haveEventsDefinition(String eventName, List eve } private static final Set skipMessages = - Set.of("$.start: string found, object expected", "$.functions: array found, object expected"); + new HashSet() { + { + add("$.start: string found, object expected"); + add("$.functions: array found, object expected"); + } + }; private void addValidationError(String message, String type) { if (skipMessages.contains(message)) { From dca3b9a0afa5fa0d0428634af415a62c230f72a9 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Fri, 20 Oct 2023 11:33:31 -0300 Subject: [PATCH 31/33] Prepare for 4.0.5 Signed-off-by: Ricardo Zanini --- .github/project.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/project.yml b/.github/project.yml index f4275350..a69b4050 100644 --- a/.github/project.yml +++ b/.github/project.yml @@ -1,3 +1,3 @@ release: - current-version: 5.0.0 - next-version: 6.0.0-SNAPSHOT \ No newline at end of file + current-version: 4.0.5 + next-version: 5.0.0-SNAPSHOT \ No newline at end of file From 985790f27b3b74d708564fc21b7da78f5b09bb0b Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Wed, 25 Oct 2023 16:34:24 +0200 Subject: [PATCH 32/33] Keep id as mandatory for backward compatibility. Signed-off-by: Francisco Javier Tirado Sarti --- api/src/main/resources/schema/workflow.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/resources/schema/workflow.json b/api/src/main/resources/schema/workflow.json index dd349995..d174cb85 100644 --- a/api/src/main/resources/schema/workflow.json +++ b/api/src/main/resources/schema/workflow.json @@ -11,7 +11,8 @@ "properties": { "id": { "type": "string", - "description": "Workflow unique identifier" + "description": "Workflow unique identifier", + "minLength": 1 }, "key": { "type": "string", From d8cb9b76110c2d4c3f6e009b1479767eb48ae4bb Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 27 Oct 2023 17:49:36 +0200 Subject: [PATCH 33/33] Force id to be mandatory Signed-off-by: Francisco Javier Tirado Sarti --- api/src/main/resources/schema/workflow.json | 1 + .../validation/test/WorkflowValidationTest.java | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/main/resources/schema/workflow.json b/api/src/main/resources/schema/workflow.json index d174cb85..f8309b6c 100644 --- a/api/src/main/resources/schema/workflow.json +++ b/api/src/main/resources/schema/workflow.json @@ -160,6 +160,7 @@ } }, "required": [ + "id", "name", "version", "states" diff --git a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java index e600e253..08237525 100644 --- a/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java +++ b/validation/src/test/java/io/serverlessworkflow/validation/test/WorkflowValidationTest.java @@ -58,7 +58,7 @@ public void testIncompleteYamlWithSchemaValidation() { List validationErrors = workflowValidator.setSource("---\n" + "key: abc\n").validate(); Assertions.assertNotNull(validationErrors); - Assertions.assertEquals(3, validationErrors.size()); + Assertions.assertEquals(4, validationErrors.size()); } @Test @@ -119,11 +119,10 @@ public void testWorkflowMissingStatesIdAndKey() { + "}") .validate(); Assertions.assertNotNull(validationErrors); - Assertions.assertEquals(2, validationErrors.size()); + Assertions.assertEquals(1, validationErrors.size()); Assertions.assertEquals( - "Workflow id or key should not be empty", validationErrors.get(0).getMessage()); - Assertions.assertEquals("No states found", validationErrors.get(1).getMessage()); + "$.id: is missing but it is required", validationErrors.get(0).getMessage()); } @Test