This is an automated email from the ASF dual-hosted git repository. liudongkai pushed a commit to branch 3.0.0-beta-2-prepare in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
commit 8aa572606ba702e35d6c6b02e60821282711d44d Author: HomminLee <[email protected]> AuthorDate: Mon Jun 27 10:19:28 2022 +0800 [Fix][dolphinscheduler-spi] json parse support LocalDateTime (#10440) * JSONUtils support LocalDateTime * remove extraneous unit tests * remove unused classes import. Co-authored-by: HomminLee <[email protected]> (cherry picked from commit dafed572d17cd08dae1c1decf389f0dd4241fdf7) --- .../dolphinscheduler/spi/utils/JSONUtils.java | 34 ++++ .../dolphinscheduler/spi/utils/JSONUtilsTest.java | 197 +++++++++++++++++++++ 2 files changed, 231 insertions(+) diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java index 3bbe770a43..5fa432a0ff 100644 --- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java +++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/utils/JSONUtils.java @@ -26,12 +26,18 @@ import static com.fasterxml.jackson.databind.MapperFeature.REQUIRE_SETTERS_FOR_G import java.io.IOException; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TimeZone; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,6 +65,10 @@ public class JSONUtils { logger.info("init timezone: {}",TimeZone.getDefault()); } + private static final SimpleModule LOCAL_DATE_TIME_MODULE = new SimpleModule() + .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()) + .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()); + /** * can use static singleton, inject: just make sure to reuse! */ @@ -67,6 +77,7 @@ public class JSONUtils { .configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true) .configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true) .configure(REQUIRE_SETTERS_FOR_GETTERS, true) + .registerModule(LOCAL_DATE_TIME_MODULE) .setTimeZone(TimeZone.getDefault()) .setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS)); @@ -289,4 +300,27 @@ public class JSONUtils { } } + + public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS); + + @Override + public void serialize(LocalDateTime value, + JsonGenerator gen, + SerializerProvider serializers) throws IOException { + gen.writeString(value.format(formatter)); + } + } + + public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> { + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS); + + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext context) throws IOException { + return LocalDateTime.parse(p.getValueAsString(), formatter); + } + } + } diff --git a/dolphinscheduler-spi/src/test/java/org/apache/dolphinscheduler/spi/utils/JSONUtilsTest.java b/dolphinscheduler-spi/src/test/java/org/apache/dolphinscheduler/spi/utils/JSONUtilsTest.java new file mode 100644 index 0000000000..fd9c75ee80 --- /dev/null +++ b/dolphinscheduler-spi/src/test/java/org/apache/dolphinscheduler/spi/utils/JSONUtilsTest.java @@ -0,0 +1,197 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dolphinscheduler.spi.utils; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +public class JSONUtilsTest { + + + @Test + public void createObjectNodeTest() { + String jsonStr = "{\"a\":\"b\",\"b\":\"d\"}"; + + ObjectNode objectNode = JSONUtils.createObjectNode(); + objectNode.put("a", "b"); + objectNode.put("b", "d"); + String s = JSONUtils.toJsonString(objectNode); + Assert.assertEquals(s, jsonStr); + } + + @Test + public void toMap() { + + String jsonStr = "{\"id\":\"1001\",\"name\":\"Jobs\"}"; + + Map<String, String> models = JSONUtils.toMap(jsonStr); + Assert.assertEquals("1001", models.get("id")); + Assert.assertEquals("Jobs", models.get("name")); + + } + + + @Test + public void string2MapTest() { + String str = list2String(); + + List<LinkedHashMap> maps = JSONUtils.toList(str, + LinkedHashMap.class); + + Assert.assertEquals(1, maps.size()); + Assert.assertEquals("mysql200", maps.get(0).get("mysql service name")); + Assert.assertEquals("192.168.xx.xx", maps.get(0).get("mysql address")); + Assert.assertEquals("3306", maps.get(0).get("port")); + Assert.assertEquals("80", maps.get(0).get("no index of number")); + Assert.assertEquals("190", maps.get(0).get("database client connections")); + } + + public String list2String() { + + LinkedHashMap<String, String> map1 = new LinkedHashMap<>(); + map1.put("mysql service name", "mysql200"); + map1.put("mysql address", "192.168.xx.xx"); + map1.put("port", "3306"); + map1.put("no index of number", "80"); + map1.put("database client connections", "190"); + + List<LinkedHashMap<String, String>> maps = new ArrayList<>(); + maps.add(0, map1); + String resultJson = JSONUtils.toJsonString(maps); + return resultJson; + } + + @Test + public void testParseObject() { + Assert.assertNull(JSONUtils.parseObject("")); + Assert.assertNull(JSONUtils.parseObject("foo", String.class)); + } + + + @Test + public void testJsonByteArray() { + String str = "foo"; + byte[] serializeByte = JSONUtils.toJsonByteArray(str); + String deserialize = JSONUtils.parseObject(serializeByte, String.class); + Assert.assertEquals(str, deserialize); + str = null; + serializeByte = JSONUtils.toJsonByteArray(str); + deserialize = JSONUtils.parseObject(serializeByte, String.class); + Assert.assertNull(deserialize); + } + + @Test + public void testToList() { + Assert.assertEquals(new ArrayList(), + JSONUtils.toList("A1B2C3", null)); + Assert.assertEquals(new ArrayList(), + JSONUtils.toList("", null)); + } + + @Test + public void testToMap() { + Map<String, String> map = new HashMap<>(); + map.put("foo", "bar"); + + Assert.assertTrue(map.equals(JSONUtils.toMap( + "{\n" + "\"foo\": \"bar\"\n" + "}"))); + + Assert.assertFalse(map.equals(JSONUtils.toMap( + "{\n" + "\"bar\": \"foo\"\n" + "}"))); + + Assert.assertNull(JSONUtils.toMap("3")); + Assert.assertNull(JSONUtils.toMap(null)); + + String str = "{\"resourceList\":[],\"localParams\":[],\"rawScript\":\"#!/bin/bash\\necho \\\"shell-1\\\"\"}"; + Map<String, String> m = JSONUtils.toMap(str); + Assert.assertNotNull(m); + } + + @Test + public void testToJsonString() { + Map<String, Object> map = new HashMap<>(); + map.put("foo", "bar"); + + Assert.assertEquals("{\"foo\":\"bar\"}", + JSONUtils.toJsonString(map)); + Assert.assertEquals(String.valueOf((Object) null), + JSONUtils.toJsonString(null)); + + Assert.assertEquals("{\"foo\":\"bar\"}", + JSONUtils.toJsonString(map, SerializationFeature.WRITE_NULL_MAP_VALUES)); + } + + @Test + public void parseObject() { + String str = "{\"color\":\"yellow\",\"type\":\"renault\"}"; + ObjectNode node = JSONUtils.parseObject(str); + + Assert.assertEquals("yellow", node.path("color").asText()); + + node.put("price", 100); + Assert.assertEquals(100, node.path("price").asInt()); + + node.put("color", "red"); + Assert.assertEquals("red", node.path("color").asText()); + } + + @Test + public void parseArray() { + String str = "[{\"color\":\"yellow\",\"type\":\"renault\"}]"; + ArrayNode node = JSONUtils.parseArray(str); + + Assert.assertEquals("yellow", node.path(0).path("color").asText()); + } + + @Test + public void localDateTimeToString() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + String time = "2022-02-22 13:38:24"; + Date date = DateUtils.stringToDate(time); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + String json = JSONUtils.toJsonString(localDateTime); + Assert.assertEquals("\"" + time + "\"", json); + } + + @Test + public void stringToLocalDateTime() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + String time = "2022-02-22 13:38:24"; + Date date = DateUtils.stringToDate(time); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + List<LocalDateTime> timeList = JSONUtils.parseObject("[\"2022-02-22 13:38:24\"]", new TypeReference<List<LocalDateTime>>(){}); + Assert.assertNotNull(timeList); + Assert.assertEquals(1, timeList.size()); + Assert.assertEquals(localDateTime, timeList.get(0)); + } + +}
