Skip to content

Commit 61d9795

Browse files
authored
fix switch condition (#15228) (#15336)
1 parent 7252e22 commit 61d9795

File tree

4 files changed

+159
-35
lines changed

4 files changed

+159
-35
lines changed

Diff for: dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/task/SwitchTaskProcessor.java

+12-34
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
import java.util.HashMap;
3838
import java.util.List;
3939
import java.util.Map;
40-
import java.util.regex.Matcher;
41-
import java.util.regex.Pattern;
4240
import java.util.stream.Collectors;
4341

4442
import com.google.auto.service.AutoService;
@@ -140,6 +138,16 @@ private boolean setSwitchResult() {
140138
switchResultVos.add(switchResultVo);
141139
int finalConditionLocation = switchResultVos.size() - 1;
142140
int i = 0;
141+
142+
Map<String, Property> globalParams = JSONUtils
143+
.toList(processInstance.getGlobalParams(), Property.class)
144+
.stream()
145+
.collect(Collectors.toMap(Property::getProp, Property -> Property));
146+
Map<String, Property> varParams = JSONUtils
147+
.toList(taskInstance.getVarPool(), Property.class)
148+
.stream()
149+
.collect(Collectors.toMap(Property::getProp, Property -> Property));
150+
143151
conditionResult = DependResult.SUCCESS;
144152
for (SwitchResultVo info : switchResultVos) {
145153
logger.info("the {} execution ", (i + 1));
@@ -148,7 +156,8 @@ private boolean setSwitchResult() {
148156
finalConditionLocation = i;
149157
break;
150158
}
151-
String content = setTaskParams(info.getCondition().replaceAll("'", "\""), rgex);
159+
String content =
160+
SwitchTaskUtils.generateContentWithTaskParams(info.getCondition(), globalParams, varParams);
152161
logger.info("format condition sentence::{}", content);
153162
Boolean result = null;
154163
try {
@@ -191,37 +200,6 @@ private void endTaskState() {
191200
processService.updateTaskInstance(taskInstance);
192201
}
193202

194-
public String setTaskParams(String content, String rgex) {
195-
Pattern pattern = Pattern.compile(rgex);
196-
Matcher m = pattern.matcher(content);
197-
Map<String, Property> globalParams = JSONUtils
198-
.toList(processInstance.getGlobalParams(), Property.class)
199-
.stream()
200-
.collect(Collectors.toMap(Property::getProp, Property -> Property));
201-
Map<String, Property> varParams = JSONUtils
202-
.toList(taskInstance.getVarPool(), Property.class)
203-
.stream()
204-
.collect(Collectors.toMap(Property::getProp, Property -> Property));
205-
if (varParams.size() > 0) {
206-
varParams.putAll(globalParams);
207-
globalParams = varParams;
208-
}
209-
while (m.find()) {
210-
String paramName = m.group(1);
211-
Property property = globalParams.get(paramName);
212-
if (property == null) {
213-
return "";
214-
}
215-
String value = property.getValue();
216-
if (!org.apache.commons.lang3.math.NumberUtils.isCreatable(value)) {
217-
value = "\"" + value + "\"";
218-
}
219-
logger.info("paramName:{},paramValue:{}", paramName, value);
220-
content = content.replace("${" + paramName + "}", value);
221-
}
222-
return content;
223-
}
224-
225203
/**
226204
* check whether switch result is valid
227205
*/

Diff for: dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/utils/SwitchTaskUtils.java

+55-1
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,29 @@
1717

1818
package org.apache.dolphinscheduler.server.master.utils;
1919

20+
import org.apache.dolphinscheduler.plugin.task.api.model.Property;
21+
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
22+
23+
import org.apache.commons.collections4.MapUtils;
24+
25+
import java.util.Map;
26+
import java.util.regex.Matcher;
27+
import java.util.regex.Pattern;
28+
2029
import javax.script.ScriptEngine;
2130
import javax.script.ScriptEngineManager;
2231
import javax.script.ScriptException;
2332

33+
import lombok.extern.slf4j.Slf4j;
34+
35+
import com.google.common.collect.Maps;
36+
37+
@Slf4j
2438
public class SwitchTaskUtils {
39+
2540
private static ScriptEngineManager manager;
2641
private static ScriptEngine engine;
42+
private static final String rgex = "['\"]*\\$\\{(.*?)\\}['\"]*";
2743

2844
static {
2945
manager = new ScriptEngineManager();
@@ -35,4 +51,42 @@ public static boolean evaluate(String expression) throws ScriptException {
3551
return (Boolean) result;
3652
}
3753

38-
}
54+
public static String generateContentWithTaskParams(String condition, Map<String, Property> globalParams,
55+
Map<String, Property> varParams) {
56+
String content = condition.replaceAll("'", "\"");
57+
if (MapUtils.isEmpty(globalParams) && MapUtils.isEmpty(varParams)) {
58+
throw new IllegalArgumentException("globalParams and varParams are both empty, please check it.");
59+
}
60+
Map<String, Property> params = Maps.newHashMap();
61+
if (MapUtils.isNotEmpty(globalParams)) {
62+
params.putAll(globalParams);
63+
}
64+
if (MapUtils.isNotEmpty(varParams)) {
65+
params.putAll(varParams);
66+
}
67+
String originContent = content;
68+
Pattern pattern = Pattern.compile(rgex);
69+
Matcher m = pattern.matcher(content);
70+
while (m.find()) {
71+
String paramName = m.group(1);
72+
Property property = params.get(paramName);
73+
if (property == null) {
74+
continue;
75+
}
76+
String value;
77+
if (ParameterUtils.isNumber(property) || ParameterUtils.isBoolean(property)) {
78+
value = "" + ParameterUtils.getParameterValue(property);
79+
} else {
80+
value = "\"" + ParameterUtils.getParameterValue(property) + "\"";
81+
}
82+
log.info("paramName:{},paramValue:{}", paramName, value);
83+
content = content.replace("${" + paramName + "}", value);
84+
}
85+
86+
// if not replace any params, throw exception to avoid illegal condition
87+
if (originContent.equals(content)) {
88+
throw new IllegalArgumentException("condition is not valid, please check it. condition: " + condition);
89+
}
90+
return content;
91+
}
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dolphinscheduler.server.master.utils;
19+
20+
import org.apache.dolphinscheduler.plugin.task.api.enums.DataType;
21+
import org.apache.dolphinscheduler.plugin.task.api.enums.Direct;
22+
import org.apache.dolphinscheduler.plugin.task.api.model.Property;
23+
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
27+
import org.junit.jupiter.api.Assertions;
28+
import org.junit.jupiter.api.Test;
29+
30+
public class SwitchTaskUtilsTest {
31+
32+
@Test
33+
public void testGenerateContentWithTaskParams() {
34+
String content = "${test}==1";
35+
Map<String, Property> globalParams = new HashMap<>();
36+
Map<String, Property> varParams = new HashMap<>();
37+
Assertions.assertThrowsExactly(IllegalArgumentException.class, () -> {
38+
SwitchTaskUtils.generateContentWithTaskParams(content, globalParams, varParams);
39+
});
40+
41+
globalParams.put("test", new Property("test", Direct.IN, DataType.INTEGER, "1"));
42+
String result = SwitchTaskUtils.generateContentWithTaskParams(content, globalParams, varParams);
43+
Assertions.assertEquals("1==1", result);
44+
}
45+
46+
@Test
47+
public void testIllegalCondition() {
48+
String content = "java.lang.Runtime.getRuntime().exec(\"bash /tmp/shell\")";
49+
Map<String, Property> globalParams = new HashMap<>();
50+
Map<String, Property> varParams = new HashMap<>();
51+
globalParams.put("test", new Property("test", Direct.IN, DataType.INTEGER, "1"));
52+
Assertions.assertThrowsExactly(IllegalArgumentException.class, () -> {
53+
SwitchTaskUtils.generateContentWithTaskParams(content, globalParams, varParams);
54+
});
55+
}
56+
}

Diff for: dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/utils/ParameterUtils.java

+36
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
import org.apache.dolphinscheduler.common.constants.DateConstants;
2121
import org.apache.dolphinscheduler.common.utils.DateUtils;
22+
import org.apache.dolphinscheduler.plugin.task.api.enums.DataType;
2223
import org.apache.dolphinscheduler.plugin.task.api.model.Property;
2324
import org.apache.dolphinscheduler.plugin.task.api.parser.PlaceholderUtils;
2425
import org.apache.dolphinscheduler.plugin.task.api.parser.TimePlaceholderUtils;
2526

2627
import org.apache.commons.lang3.StringUtils;
2728

29+
import java.io.Serializable;
2830
import java.util.Date;
2931
import java.util.HashMap;
3032
import java.util.Iterator;
@@ -130,4 +132,38 @@ private static String dateTemplateParse(String templateStr, Date date) {
130132
return newValue.toString();
131133
}
132134

135+
public static Serializable getParameterValue(Property property) {
136+
if (property == null) {
137+
return null;
138+
}
139+
String value = property.getValue();
140+
switch (property.getType()) {
141+
case LONG:
142+
return Long.valueOf(value);
143+
case FLOAT:
144+
return Float.valueOf(value);
145+
case INTEGER:
146+
return Integer.valueOf(value);
147+
case DOUBLE:
148+
return Double.valueOf(value);
149+
case BOOLEAN:
150+
return Boolean.valueOf(value);
151+
// todo: add date type, list type....
152+
default:
153+
return value;
154+
}
155+
}
156+
157+
public static boolean isNumber(Property property) {
158+
return property != null &&
159+
(DataType.INTEGER.equals(property.getType())
160+
|| DataType.LONG.equals(property.getType())
161+
|| DataType.FLOAT.equals(property.getType())
162+
|| DataType.DOUBLE.equals(property.getType()));
163+
}
164+
165+
public static boolean isBoolean(Property property) {
166+
return property != null && DataType.BOOLEAN.equals(property.getType());
167+
}
168+
133169
}

0 commit comments

Comments
 (0)