-
Notifications
You must be signed in to change notification settings - Fork 281
Make step param separator configurable to allow __ in step IDs and param names #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
90d59de
bbe94c7
298334d
7aa91c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| /* | ||
| * Copyright 2024 Netflix, 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. | ||
| */ | ||
| package com.netflix.maestro.utils; | ||
|
|
||
| /** Interface for providing the configured step parameter separator string. */ | ||
| @FunctionalInterface | ||
| public interface StepParamSeparator { | ||
|
|
||
| /** Returns the separator used in cross-step parameter references (e.g. {@code step1__param}). */ | ||
| String getStepParamSeparator(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,13 +59,18 @@ | |
| @Slf4j | ||
| @AllArgsConstructor | ||
| public class ParamEvaluator { | ||
| private static final String STEP_PARAM_SEPARATOR = "__"; | ||
| private static final String SIGNAL_EXPRESSION_TEMPLATE = | ||
| "return params.getFromSignal('%s', '%s');"; | ||
| private static final String PARAM_NAME_FOR_ALL = "params"; | ||
|
|
||
| private final ExprEvaluator exprEvaluator; | ||
| private final ObjectMapper objectMapper; | ||
| private final String stepParamSeparator; | ||
|
|
||
| /** Convenience constructor using the default step param separator {@code __}. */ | ||
| public ParamEvaluator(ExprEvaluator exprEvaluator, ObjectMapper objectMapper) { | ||
| this(exprEvaluator, objectMapper, Constants.DEFAULT_STEP_PARAM_SEPARATOR); | ||
| } | ||
|
|
||
| /** | ||
| * Evaluate workflow parameters. | ||
|
|
@@ -154,7 +159,7 @@ private Map<String, Parameter> getReferencedParams( | |
| parseWorkflowParameter( | ||
| workflowParams, workflowParams.get(refParamName), workflowId, visited); | ||
| refParams.put(refParamName, workflowParams.get(refParamName)); | ||
| } else if (refParamName.contains(STEP_PARAM_SEPARATOR)) { | ||
| } else if (refParamName.contains(stepParamSeparator)) { | ||
| // here it might be from signal triggers | ||
| Map.Entry<String, String> pair = parseReferenceName(refParamName, Collections.emptyMap()); | ||
| refParams.put( | ||
|
|
@@ -313,7 +318,7 @@ private Map<String, Parameter> getReferencedParams( | |
| Set<String> visited) { | ||
| Map<String, Parameter> usedParams = new HashMap<>(); | ||
| for (String refParam : refParamNames) { | ||
| if (refParam.contains(STEP_PARAM_SEPARATOR)) { | ||
| if (refParam.contains(stepParamSeparator)) { | ||
| usedParams.put( | ||
| refParam, | ||
| getReferenceParam( | ||
|
|
@@ -350,11 +355,15 @@ private Map<String, Parameter> getReferencedParams( | |
| return usedParams; | ||
| } | ||
|
|
||
| /** Extract step id and param name from the reference. It handles `__`, `___`, and `____`. */ | ||
| /** | ||
| * Extract step id and param name from the reference. It handles separator, separator with one | ||
| * extra underscore, and separator with two extra underscores (e.g. {@code __}, {@code ___}, and | ||
| * {@code ____} for the default separator). | ||
| */ | ||
| private Map.Entry<String, String> parseReferenceName( | ||
| String refParam, Map<String, Map<String, Object>> allStepOutputData) { | ||
| int idx1 = refParam.indexOf(STEP_PARAM_SEPARATOR); | ||
| int idx2 = refParam.lastIndexOf(STEP_PARAM_SEPARATOR); | ||
| int idx1 = refParam.indexOf(stepParamSeparator); | ||
| int idx2 = refParam.lastIndexOf(stepParamSeparator); | ||
| // ___ or ____ case | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The inline comment on the |
||
| if (idx1 != idx2) { | ||
| String id1 = refParam.substring(0, idx1); | ||
|
|
@@ -374,7 +383,7 @@ private Map.Entry<String, String> parseReferenceName( | |
| } | ||
| } | ||
| String refStepId = refParam.substring(0, idx1); | ||
| String refParamName = refParam.substring(idx1 + 2); | ||
| String refParamName = refParam.substring(idx1 + stepParamSeparator.length()); | ||
| return new AbstractMap.SimpleEntry<>(refStepId, refParamName); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,5 +27,11 @@ | |
| public class MaestroProperties { | ||
| private final QueueProperties queue; | ||
| private final SelProperties sel; | ||
| private final ParamEvaluatorProperties paramEvaluator; | ||
| private final StepActionProperties stepAction; | ||
|
|
||
| /** Returns the param evaluator properties, defaulting to {@code __} separator if not set. */ | ||
| public ParamEvaluatorProperties getParamEvaluator() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The custom getter that overrides Lombok's
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The asymmetry is intentional. queue, sel, and stepAction are pre-existing required fields, if absent the app should fail to start.
Happy to switch to a manual constructor with @DefaultValue if you prefer consistency over brevity. |
||
| return paramEvaluator != null ? paramEvaluator : new ParamEvaluatorProperties(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| /* | ||
| * Copyright 2024 Netflix, 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. | ||
| */ | ||
| package com.netflix.maestro.server.properties; | ||
|
|
||
| import com.netflix.maestro.models.Constants; | ||
| import com.netflix.maestro.utils.StepParamSeparator; | ||
| import lombok.Getter; | ||
| import lombok.Setter; | ||
|
|
||
| /** | ||
| * Parameter evaluator properties. Please check {@link | ||
| * com.netflix.maestro.engine.eval.ParamEvaluator} about how they are used. | ||
| */ | ||
| @Getter | ||
| @Setter | ||
| public class ParamEvaluatorProperties implements StepParamSeparator { | ||
| private String stepParamSeparator = Constants.DEFAULT_STEP_PARAM_SEPARATOR; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this deletion intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes to fix the build check. markTransactionSerializable is added twice in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, unrelated but this is to fix the broken build.