Skip to content

Commit 79f686f

Browse files
authored
[Improvement-17267] Throw exception if deserialize json failed in JSONUtils (#17243)
1 parent 342c471 commit 79f686f

22 files changed

Lines changed: 334 additions & 296 deletions

File tree

dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-email/src/test/java/org/apache/dolphinscheduler/plugin/alert/email/ExcelUtilsTest.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
package org.apache.dolphinscheduler.plugin.alert.email;
1919

20-
import org.apache.dolphinscheduler.plugin.alert.email.exception.AlertEmailException;
21-
2220
import java.io.File;
2321
import java.nio.file.Path;
2422

@@ -35,7 +33,7 @@ public class ExcelUtilsTest {
3533
private String xlsFilePath;
3634

3735
@BeforeEach
38-
public void setUp() throws Exception {
36+
public void setUp() {
3937
xlsFilePath = testFolder.toString();
4038
}
4139

@@ -58,9 +56,8 @@ public void testGenExcelFile() {
5856
Assertions.assertTrue(xlsFile.exists());
5957

6058
// Invoke genExcelFile with incorrectContent, will cause RuntimeException
61-
Assertions.assertThrows(AlertEmailException.class, () -> {
62-
ExcelUtils.genExcelFile(incorrectContent1, title, xlsFilePath);
63-
});
59+
Assertions.assertThrows(IllegalArgumentException.class,
60+
() -> ExcelUtils.genExcelFile(incorrectContent1, title, xlsFilePath));
6461

6562
}
6663

dolphinscheduler-alert/dolphinscheduler-alert-plugins/dolphinscheduler-alert-feishu/src/test/java/org/apache/dolphinscheduler/plugin/alert/feishu/FeiShuSenderTest.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,22 @@ public void testFormatContent() {
7676
public void testSendWithFormatException() {
7777
AlertData alertData = new AlertData();
7878
alertData.setTitle("feishu test title");
79-
alertData.setContent("feishu test content");
80-
FeiShuSender feiShuSender = new FeiShuSender(feiShuConfig);
81-
String alertResult = feiShuSender.formatContent(alertData);
82-
Assertions.assertEquals(alertResult, alertData.getTitle() + alertData.getContent());
79+
alertData.setContent("[{\"content\":\"feishu test content\"}]");
80+
String alertResult = FeiShuSender.formatContent(alertData);
81+
Assertions.assertEquals(alertResult, "`feishu test title`\ncontent:feishu test content\n");
8382
}
8483

8584
@Test
8685
public void testCheckSendFeiShuSendMsgResult() {
8786

88-
FeiShuSender feiShuSender = new FeiShuSender(feiShuConfig);
89-
AlertResult alertResult = feiShuSender.checkSendFeiShuSendMsgResult("");
87+
AlertResult alertResult = FeiShuSender.checkSendFeiShuSendMsgResult("");
9088
Assertions.assertFalse(alertResult.isSuccess());
91-
AlertResult alertResult2 = feiShuSender.checkSendFeiShuSendMsgResult("123");
92-
Assertions.assertEquals("send feishu msg error: feishu server resp parse error is null.",
89+
AlertResult alertResult2 = FeiShuSender.checkSendFeiShuSendMsgResult("{\"code\":123}");
90+
Assertions.assertEquals("alert send feishu msg error: null",
9391
alertResult2.getMessage());
9492

9593
String response = "{\"code\":\"0\",\"data\":{},\"msg\":\"success\"}";
96-
AlertResult alertResult3 = feiShuSender.checkSendFeiShuSendMsgResult(response);
94+
AlertResult alertResult3 = FeiShuSender.checkSendFeiShuSendMsgResult(response);
9795
Assertions.assertTrue(alertResult3.isSuccess());
9896
}
9997
}

dolphinscheduler-alert/dolphinscheduler-alert-server/src/test/java/org/apache/dolphinscheduler/alert/runner/AlertSenderTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ void testSyncHandler() {
9696

9797
// 2.alert plugin does not exist
9898
int pluginDefineId = 1;
99-
String pluginInstanceParams = "alert-instance-mail-params";
10099
String pluginInstanceName = "alert-instance-mail";
101100
List<AlertPluginInstance> alertInstanceList = new ArrayList<>();
102101
AlertPluginInstance alertPluginInstance = new AlertPluginInstance(
103-
pluginDefineId, pluginInstanceParams, pluginInstanceName);
102+
pluginDefineId, PLUGIN_INSTANCE_PARAMS, pluginInstanceName);
104103
alertPluginInstance.setId(1);
105104
alertInstanceList.add(alertPluginInstance);
106105
when(alertDao.listInstanceByAlertGroupId(1)).thenReturn(alertInstanceList);

dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/EnvironmentServiceImpl.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,10 +475,11 @@ protected void checkParams(String name, String config, String workerGroups) {
475475
if (StringUtils.isEmpty(config)) {
476476
throw new ServiceException(Status.ENVIRONMENT_CONFIG_IS_NULL);
477477
}
478-
if (!StringUtils.isEmpty(workerGroups)) {
479-
List<String> workerGroupList = JSONUtils.parseObject(workerGroups, new TypeReference<List<String>>() {
480-
});
481-
if (Objects.isNull(workerGroupList)) {
478+
if (StringUtils.isNotEmpty(workerGroups)) {
479+
try {
480+
JSONUtils.parseObject(workerGroups, new TypeReference<List<String>>() {
481+
});
482+
} catch (IllegalArgumentException e) {
482483
throw new ServiceException(Status.ENVIRONMENT_WORKER_GROUPS_IS_INVALID);
483484
}
484485
}

dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.dolphinscheduler.api.utils.PageInfo;
2929
import org.apache.dolphinscheduler.api.utils.Result;
3030
import org.apache.dolphinscheduler.common.constants.Constants;
31+
import org.apache.dolphinscheduler.common.constants.SystemConstants;
3132
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
3233
import org.apache.dolphinscheduler.common.enums.Flag;
3334
import org.apache.dolphinscheduler.common.enums.UserType;
@@ -63,7 +64,6 @@
6364
import java.util.Map;
6465
import java.util.Objects;
6566
import java.util.Set;
66-
import java.util.TimeZone;
6767
import java.util.stream.Collectors;
6868

6969
import lombok.extern.slf4j.Slf4j;
@@ -891,7 +891,7 @@ public Map<String, Object> getUserInfo(User loginUser) {
891891

892892
// add system default timezone if not user timezone
893893
if (StringUtils.isEmpty(user.getTimeZone())) {
894-
user.setTimeZone(TimeZone.getDefault().toZoneId().getId());
894+
user.setTimeZone(SystemConstants.DEFAULT_TIME_ZONE.toZoneId().getId());
895895
}
896896

897897
// remove password

dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ public void testQueryTaskListByWorkflowInstanceId() throws IOException {
480480
taskInstanceContext.setContextType(ContextType.DEPENDENT_RESULT_CONTEXT);
481481
DependentResultTaskInstanceContext dependentResultTaskInstanceContext =
482482
new DependentResultTaskInstanceContext();
483+
dependentResultTaskInstanceContext.setContextType(ContextType.DEPENDENT_RESULT_CONTEXT);
483484
dependentResultTaskInstanceContext.setProjectCode(projectCode);
484485
dependentResultTaskInstanceContext.setDependentResult(DependResult.SUCCESS);
485486
taskInstanceContext.setTaskInstanceContext(
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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.common.constants;
19+
20+
import java.util.TimeZone;
21+
22+
import lombok.extern.slf4j.Slf4j;
23+
24+
@Slf4j
25+
public class SystemConstants {
26+
27+
public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getDefault();
28+
29+
static {
30+
log.info("init timezone: {}", DEFAULT_TIME_ZONE);
31+
}
32+
}

dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/JSONUtils.java

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import static java.nio.charset.StandardCharsets.UTF_8;
2626
import static org.apache.dolphinscheduler.common.constants.DateConstants.YYYY_MM_DD_HH_MM_SS;
2727

28+
import org.apache.dolphinscheduler.common.constants.SystemConstants;
29+
2830
import org.apache.commons.lang3.StringUtils;
2931

3032
import java.io.IOException;
@@ -69,10 +71,6 @@
6971
@Slf4j
7072
public final class JSONUtils {
7173

72-
static {
73-
log.info("init timezone: {}", TimeZone.getDefault());
74-
}
75-
7674
private static final ObjectMapper objectMapper = JsonMapper.builder()
7775
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
7876
.configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true)
@@ -83,7 +81,7 @@ public final class JSONUtils {
8381
.addModule(new SimpleModule()
8482
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer())
8583
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()))
86-
.defaultTimeZone(TimeZone.getDefault())
84+
.defaultTimeZone(SystemConstants.DEFAULT_TIME_ZONE)
8785
.defaultDateFormat(new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS))
8886
.build();
8987

@@ -110,7 +108,7 @@ public static JsonNode toJsonNode(Object obj) {
110108
/**
111109
* json representation of object
112110
*
113-
* @param object object
111+
* @param object object
114112
* @param feature feature
115113
* @return object to json string
116114
*/
@@ -133,31 +131,34 @@ public static String toJsonString(Object object, SerializationFeature feature) {
133131
* the fields of the specified object are generics, just the object itself should not be a
134132
* generic type.
135133
*
136-
* @param json the string from which the object is to be deserialized
134+
* @param json the string from which the object is to be deserialized
137135
* @param clazz the class of T
138-
* @param <T> T
136+
* @param <T> T
139137
* @return an object of type T from the string
140138
* classOfT
141139
*/
142140
public static @Nullable <T> T parseObject(String json, Class<T> clazz) {
141+
if (clazz == null) {
142+
throw new IllegalArgumentException("Class type cannot be null");
143+
}
144+
143145
if (Strings.isNullOrEmpty(json)) {
144146
return null;
145147
}
146148

147149
try {
148150
return objectMapper.readValue(json, clazz);
149151
} catch (Exception e) {
150-
log.error("Parse object exception, jsonStr: {}, class: {}", json, clazz, e);
152+
throw new IllegalArgumentException("Parse json: " + json + " to class: " + clazz.getName() + " failed", e);
151153
}
152-
return null;
153154
}
154155

155156
/**
156-
* deserialize
157+
* deserialize
157158
*
158-
* @param src byte array
159+
* @param src byte array
159160
* @param clazz class
160-
* @param <T> deserialize type
161+
* @param <T> deserialize type
161162
* @return deserialize type
162163
*/
163164
public static <T> T parseObject(byte[] src, Class<T> clazz) {
@@ -171,12 +172,16 @@ public static <T> T parseObject(byte[] src, Class<T> clazz) {
171172
/**
172173
* json to list
173174
*
174-
* @param json json string
175+
* @param json json string
175176
* @param clazz class
176-
* @param <T> T
177+
* @param <T> T
177178
* @return list
178179
*/
179180
public static <T> List<T> toList(String json, Class<T> clazz) {
181+
if (clazz == null) {
182+
throw new IllegalArgumentException("Class type cannot be null");
183+
}
184+
180185
if (Strings.isNullOrEmpty(json)) {
181186
return Collections.emptyList();
182187
}
@@ -185,10 +190,10 @@ public static <T> List<T> toList(String json, Class<T> clazz) {
185190
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
186191
return objectMapper.readValue(json, listType);
187192
} catch (Exception e) {
188-
log.error("parse list exception!", e);
193+
throw new IllegalArgumentException(
194+
"Parse json: " + json + " to list of class: " + clazz.getName() + " failed", e);
189195
}
190196

191-
return Collections.emptyList();
192197
}
193198

194199
/**
@@ -222,7 +227,7 @@ public static boolean checkJsonValid(String json, Boolean logFlag) {
222227
* node or its child nodes, and returning value it has.
223228
* If no matching field is found in this node or its descendants, returns null.
224229
*
225-
* @param jsonNode json node
230+
* @param jsonNode json node
226231
* @param fieldName Name of field to look for
227232
* @return Value of first matching node found, if any; null if none
228233
*/
@@ -238,7 +243,6 @@ public static String findValue(JsonNode jsonNode, String fieldName) {
238243

239244
/**
240245
* json to map
241-
* {@link #toMap(String, Class, Class)}
242246
*
243247
* @param json json
244248
* @return json to map
@@ -248,34 +252,10 @@ public static Map<String, String> toMap(String json) {
248252
});
249253
}
250254

251-
/**
252-
* json to map
253-
*
254-
* @param json json
255-
* @param classK classK
256-
* @param classV classV
257-
* @param <K> K
258-
* @param <V> V
259-
* @return to map
260-
*/
261-
public static <K, V> Map<K, V> toMap(String json, Class<K> classK, Class<V> classV) {
262-
if (Strings.isNullOrEmpty(json)) {
263-
return Collections.emptyMap();
264-
}
265-
266-
try {
267-
return objectMapper.readValue(json, new TypeReference<Map<K, V>>() {
268-
});
269-
} catch (Exception e) {
270-
log.error("json to map exception!", e);
271-
}
272-
273-
return Collections.emptyMap();
274-
}
275-
276255
/**
277256
* from the key-value generated json to get the str value no matter the real type of value
278-
* @param json the json str
257+
*
258+
* @param json the json str
279259
* @param nodeName key
280260
* @return the str value of key
281261
*/
@@ -305,13 +285,15 @@ public static <T> T parseObject(String json, TypeReference<T> type) {
305285
return null;
306286
}
307287

288+
if (type == null) {
289+
throw new IllegalArgumentException("Type reference cannot be null");
290+
}
291+
308292
try {
309293
return objectMapper.readValue(json, type);
310294
} catch (Exception e) {
311-
log.error("json to map exception!", e);
295+
throw new IllegalArgumentException("Parse json: " + json + " to type: " + type.getType() + " failed", e);
312296
}
313-
314-
return null;
315297
}
316298

317299
/**
@@ -347,14 +329,12 @@ public static <T> byte[] toJsonByteArray(T obj) {
347329
if (obj == null) {
348330
return null;
349331
}
350-
String json = "";
351332
try {
352-
json = toJsonString(obj);
333+
return toJsonString(obj).getBytes(UTF_8);
353334
} catch (Exception e) {
354-
log.error("json serialize exception.", e);
335+
throw new IllegalArgumentException("Object: " + obj + " to json serialization exception.", e);
355336
}
356337

357-
return json.getBytes(UTF_8);
358338
}
359339

360340
public static ObjectNode parseObject(String text) {

0 commit comments

Comments
 (0)