From 8d4a7f00dba0621c4025766b26abd8daf54c94db Mon Sep 17 00:00:00 2001 From: brig Date: Wed, 4 Oct 2023 13:16:35 +0200 Subject: [PATCH 1/3] runtime-v2: logYaml step --- plugins/tasks/log/pom.xml | 21 +++++++++ .../concord/plugins/log/LoggingTaskV2.java | 44 ++++++++++++++++--- .../concord/runtime/v2/parser/GrammarV2.java | 3 +- .../concord/runtime/v2/parser/LogGrammar.java | 12 ++++- .../runtime/v2/schema/LogYamlStepMixIn.java | 38 ++++++++++++++++ .../concord/runtime/v2/schema/StepMixIn.java | 1 + .../concord/runtime/v2/runner/MainTest.java | 1 + .../runtime/v2/runner/hello/concord.yml | 4 +- 8 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/LogYamlStepMixIn.java diff --git a/plugins/tasks/log/pom.xml b/plugins/tasks/log/pom.xml index 2954148bd1..9766792d8e 100644 --- a/plugins/tasks/log/pom.xml +++ b/plugins/tasks/log/pom.xml @@ -24,6 +24,27 @@ provided + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + + javax.inject javax.inject diff --git a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java index f5b6c076bb..495e769fd6 100644 --- a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java +++ b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java @@ -20,40 +20,48 @@ * ===== */ +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.walmartlabs.concord.runtime.v2.sdk.Task; import com.walmartlabs.concord.runtime.v2.sdk.TaskResult; import com.walmartlabs.concord.runtime.v2.sdk.Variables; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import javax.inject.Named; -import java.io.Serializable; @Named("log") public class LoggingTaskV2 implements Task { + private static final ObjectMapper yamlObjectMapper = createYamlObjectMapper(); + @Override public TaskResult execute(Variables variables) { Object msg = variables.get("msg"); + String format = variables.getString("format"); String logLevel = variables.getString("level", "INFO"); switch (logLevel.toUpperCase()) { case "DEBUG": { - LogUtils.debug(msg); + LogUtils.debug(formatMessage(format, msg)); break; } case "INFO": { - LogUtils.info(msg); + LogUtils.info(formatMessage(format, msg)); break; } case "WARN": { - LogUtils.warn(msg); + LogUtils.warn(formatMessage(format, msg)); break; } case "ERROR": { - LogUtils.error(msg); + LogUtils.error(formatMessage(format, msg)); break; } default: - LogUtils.info(msg); + LogUtils.info(formatMessage(format, msg)); } return TaskResult.success(); @@ -94,4 +102,28 @@ public static void error(Object o) { public void call(String s) { LogUtils.info(s); } + + private static Object formatMessage(String format, Object msg) { + if ("yaml".equalsIgnoreCase(format)) { + try { + return "\n" + yamlObjectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(msg); + } catch (Exception e) { + throw new RuntimeException("Invalid yaml:" + e.getMessage()); + } + } + + return msg; + } + + private static ObjectMapper createYamlObjectMapper() { + return defaultObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); + } + + private static ObjectMapper defaultObjectMapper(JsonFactory jf) { + ObjectMapper om = new ObjectMapper(jf); + om.registerModule(new Jdk8Module()); + om.registerModule(new JavaTimeModule()); + return om; + } } diff --git a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/GrammarV2.java b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/GrammarV2.java index 78d2ece4d9..96e9850957 100644 --- a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/GrammarV2.java +++ b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/GrammarV2.java @@ -47,6 +47,7 @@ import static com.walmartlabs.concord.runtime.v2.parser.GrammarMisc.*; import static com.walmartlabs.concord.runtime.v2.parser.GroupOfStepsGrammar.group; import static com.walmartlabs.concord.runtime.v2.parser.LogGrammar.logStep; +import static com.walmartlabs.concord.runtime.v2.parser.LogGrammar.logYamlStep; import static com.walmartlabs.concord.runtime.v2.parser.ParallelGrammar.parallelBlock; import static com.walmartlabs.concord.runtime.v2.parser.ReturnGrammar.returnStep; import static com.walmartlabs.concord.runtime.v2.parser.ScriptGrammar.script; @@ -181,7 +182,7 @@ private static Parser _val(JsonToken t) { private static final Parser stepObject = betweenTokens(JsonToken.START_OBJECT, JsonToken.END_OBJECT, choice(choice(parallelBlock, group, exprFull), choice(taskFull, script, callFull, callForm), - choice(checkpoint, ifExpr, switchExpr), setVars, logStep, throwStep, suspendStep)); + choice(checkpoint, ifExpr, switchExpr, setVars), logStep, logYamlStep, throwStep, suspendStep)); // step := exit | exprShort | parallelBlock | stepObject private static final Parser step = orError(choice(exit, returnStep, exprShort, stepObject), YamlValueType.STEP); diff --git a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/LogGrammar.java b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/LogGrammar.java index 5350bf4aae..75b5f872fb 100644 --- a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/LogGrammar.java +++ b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/parser/LogGrammar.java @@ -26,18 +26,26 @@ import static com.walmartlabs.concord.runtime.v2.parser.GrammarMisc.namedStep; import static com.walmartlabs.concord.runtime.v2.parser.GrammarOptions.namedOptions; import static com.walmartlabs.concord.runtime.v2.parser.GrammarV2.anyVal; -import static com.walmartlabs.concord.runtime.v2.parser.TaskGrammar.optionsWithStepName; public final class LogGrammar { public static final Parser logStep = namedStep("log", YamlValueType.TASK, (stepName, a) -> anyVal.bind(msg -> - namedOptions.map(options -> new TaskCall(a.location, "log", optionsWithStepName(stepName) + namedOptions.map(options -> new TaskCall(a.location, "log", TaskGrammar.optionsWithStepName(stepName) .putInput("msg", msg) .putAllMeta(options.meta()) .build())))); + public static final Parser logYamlStep = + namedStep("logYaml", YamlValueType.TASK, (stepName, a) -> + anyVal.bind(msg -> + namedOptions.map(options -> new TaskCall(a.location, "log", TaskGrammar.optionsWithStepName(stepName) + .putInput("msg", msg) + .putInput("format", "yaml") + .putAllMeta(options.meta()) + .build())))); + private LogGrammar() { } } diff --git a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/LogYamlStepMixIn.java b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/LogYamlStepMixIn.java new file mode 100644 index 0000000000..d77018eccc --- /dev/null +++ b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/LogYamlStepMixIn.java @@ -0,0 +1,38 @@ +package com.walmartlabs.concord.runtime.v2.schema; + +/*- + * ***** + * Concord + * ----- + * Copyright (C) 2017 - 2020 Walmart Inc. + * ----- + * 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. + * ===== + */ + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle; + +import java.util.Map; + +@JsonTypeName("LogYamlStep") +public interface LogYamlStepMixIn extends NamedStep { + + @JsonProperty(value = "logYaml", required = true) + @JsonSchemaTitle("Log yaml step") + String logYaml(); + + @JsonProperty("meta") + Map meta(); +} diff --git a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/StepMixIn.java b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/StepMixIn.java index 8e475bc430..d8100fba99 100644 --- a/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/StepMixIn.java +++ b/runtime/v2/model/src/main/java/com/walmartlabs/concord/runtime/v2/schema/StepMixIn.java @@ -36,6 +36,7 @@ @JsonSubTypes.Type(value = ExpressionShortMixIn.class, name = "Expression (short form)"), @JsonSubTypes.Type(value = ExpressionFullMixIn.class, name = "Expression (full form)"), @JsonSubTypes.Type(value = LogStepMixIn.class, name = "Log"), + @JsonSubTypes.Type(value = LogYamlStepMixIn.class, name = "LogYaml"), @JsonSubTypes.Type(value = FlowCallStepMixIn.class, name = "Flow call"), @JsonSubTypes.Type(value = FormCallStepMixIn.class, name = "Form call"), @JsonSubTypes.Type(value = IfStepMixIn.class, name = "IF step"), diff --git a/runtime/v2/runner/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java b/runtime/v2/runner/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java index b804e05c10..fc0d075809 100644 --- a/runtime/v2/runner/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java +++ b/runtime/v2/runner/src/test/java/com/walmartlabs/concord/runtime/v2/runner/MainTest.java @@ -227,6 +227,7 @@ public void test() throws Exception { byte[] log = run(); assertLog(log, ".*Hello, Concord!.*"); assertLog(log, ".*" + Pattern.quote("defaultsMap:{a=a-value}") + ".*"); + assertLog(log, ".*k: \"value\".*"); verify(processStatusCallback, times(1)).onRunning(instanceId); } diff --git a/runtime/v2/runner/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/hello/concord.yml b/runtime/v2/runner/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/hello/concord.yml index b3237fdb4b..f3a35ae0a0 100644 --- a/runtime/v2/runner/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/hello/concord.yml +++ b/runtime/v2/runner/src/test/resources/com/walmartlabs/concord/runtime/v2/runner/hello/concord.yml @@ -1,4 +1,6 @@ flows: default: - log: "Hello, ${name}!" - - task: testDefaults \ No newline at end of file + - task: testDefaults + - logYaml: + k: "value" \ No newline at end of file From 20e5941f3bb52f2a828c8c05872c37d5726e2289 Mon Sep 17 00:00:00 2001 From: brig Date: Mon, 25 Dec 2023 11:47:11 +0100 Subject: [PATCH 2/3] review up --- .../com/walmartlabs/concord/plugins/log/LoggingTaskV2.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java index 495e769fd6..811101437a 100644 --- a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java +++ b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java @@ -104,6 +104,10 @@ public void call(String s) { } private static Object formatMessage(String format, Object msg) { + if (format == null || format.trim().isEmpty()) { + return msg; + } + if ("yaml".equalsIgnoreCase(format)) { try { return "\n" + yamlObjectMapper.writerWithDefaultPrettyPrinter() @@ -113,7 +117,7 @@ private static Object formatMessage(String format, Object msg) { } } - return msg; + throw new IllegalArgumentException("Unknown format '" + format + "'"); } private static ObjectMapper createYamlObjectMapper() { From 9140bf0c50cdd8033872f3b4813037e245340887 Mon Sep 17 00:00:00 2001 From: Yury Brigadirenko Date: Sun, 24 Mar 2024 23:12:24 +0100 Subject: [PATCH 3/3] disable(YAMLGenerator.Feature.SPLIT_LINES) --- .../com/walmartlabs/concord/plugins/log/LoggingTaskV2.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java index 811101437a..3884f0473d 100644 --- a/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java +++ b/plugins/tasks/log/src/main/java/com/walmartlabs/concord/plugins/log/LoggingTaskV2.java @@ -121,7 +121,9 @@ private static Object formatMessage(String format, Object msg) { } private static ObjectMapper createYamlObjectMapper() { - return defaultObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); + return defaultObjectMapper(new YAMLFactory() + .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) + .disable(YAMLGenerator.Feature.SPLIT_LINES)); } private static ObjectMapper defaultObjectMapper(JsonFactory jf) {