summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java14
-rw-r--r--gson/src/main/java/org/onap/policy/common/gson/JacksonHandler.java4
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlExceptionMapper.java2
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlJacksonHandler.java51
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java54
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java3
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java3
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java10
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlJacksonHandlerTest.java172
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java2
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java3
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java217
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java321
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java24
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java100
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/coder/YamlJsonTranslatorTest.java170
-rw-r--r--utils/src/test/resources/org/onap/policy/common/utils/coder/YamlJsonTranslator.yaml (renamed from utils/src/test/resources/org/onap/policy/common/utils/coder/StandardYamlCoder.yaml)0
17 files changed, 816 insertions, 334 deletions
diff --git a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java
index a36f8a07..ad270910 100644
--- a/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java
+++ b/gson/src/main/java/org/onap/policy/common/gson/GsonMessageBodyHandler.java
@@ -62,9 +62,17 @@ public class GsonMessageBodyHandler implements MessageBodyReader<Object>, Messag
* into Integer/Long, where possible.
*/
public GsonMessageBodyHandler() {
- this(new GsonBuilder().registerTypeAdapterFactory(new MapDoubleAdapterFactory()).create());
+ this(new GsonBuilder());
+ }
- logger.info("Using GSON for REST calls");
+ /**
+ * Constructs the object, using a Gson object that translates Doubles inside of Maps
+ * into Integer/Long, where possible.
+ *
+ * @param builder builder to use to create the gson object
+ */
+ public GsonMessageBodyHandler(GsonBuilder builder) {
+ this(builder.registerTypeAdapterFactory(new MapDoubleAdapterFactory()).create());
}
/**
@@ -74,6 +82,8 @@ public class GsonMessageBodyHandler implements MessageBodyReader<Object>, Messag
*/
public GsonMessageBodyHandler(Gson gson) {
this.gson = gson;
+
+ logger.info("Using GSON for REST calls");
}
@Override
diff --git a/gson/src/main/java/org/onap/policy/common/gson/JacksonHandler.java b/gson/src/main/java/org/onap/policy/common/gson/JacksonHandler.java
index ad9692f4..6d946439 100644
--- a/gson/src/main/java/org/onap/policy/common/gson/JacksonHandler.java
+++ b/gson/src/main/java/org/onap/policy/common/gson/JacksonHandler.java
@@ -49,9 +49,7 @@ public class JacksonHandler extends GsonMessageBodyHandler {
super(builder
.registerTypeAdapterFactory(new JacksonFieldAdapterFactory())
.registerTypeAdapterFactory(new JacksonMethodAdapterFactory())
- .registerTypeAdapterFactory(new MapDoubleAdapterFactory())
- .setExclusionStrategies(new JacksonExclusionStrategy())
- .create());
+ .setExclusionStrategies(new JacksonExclusionStrategy()));
}
}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlExceptionMapper.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlExceptionMapper.java
index ac96cab0..7eac932a 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlExceptionMapper.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlExceptionMapper.java
@@ -34,7 +34,7 @@ import org.yaml.snakeyaml.error.YAMLException;
* error code to an HTTP 400 error code.
*/
@Provider
-@Produces("application/yaml")
+@Produces(YamlMessageBodyHandler.APPLICATION_YAML)
public class YamlExceptionMapper implements ExceptionMapper<YAMLException> {
private static Logger logger = LoggerFactory.getLogger(YamlExceptionMapper.class);
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlJacksonHandler.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlJacksonHandler.java
new file mode 100644
index 00000000..0cab374f
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlJacksonHandler.java
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.endpoints.http.server;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.Provider;
+import org.onap.policy.common.gson.JacksonHandler;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+
+/**
+ * Provider that serializes and de-serializes YAML via snakeyaml and gson using jackson
+ * default behaviors and annotations.
+ */
+@Provider
+@Consumes(MediaType.WILDCARD)
+@Produces(MediaType.WILDCARD)
+public class YamlJacksonHandler extends YamlMessageBodyHandler {
+
+ /**
+ * Translator to be used. We want a GSON object that's configured the same way as it
+ * is in {@link JacksonHandler}, so just get it from there.
+ */
+ private static final YamlJsonTranslator TRANS = new YamlJsonTranslator(new JacksonHandler().getGson());
+
+ /**
+ * Constructs the object.
+ */
+ public YamlJacksonHandler() {
+ super(TRANS);
+ }
+}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java
index 36418e4a..89aa8ff6 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java
@@ -26,7 +26,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
@@ -37,14 +36,14 @@ import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
-import org.onap.policy.common.utils.coder.CoderException;
-import org.onap.policy.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.error.YAMLException;
/**
- * Provider that serializes and de-serializes JSON via gson.
+ * Provider that serializes and de-serializes YAML via snakeyaml and gson.
*/
@Provider
@Consumes(MediaType.WILDCARD)
@@ -53,11 +52,33 @@ public class YamlMessageBodyHandler implements MessageBodyReader<Object>, Messag
public static final Logger logger = LoggerFactory.getLogger(YamlMessageBodyHandler.class);
+ public static final String APPLICATION_YAML = "application/yaml";
+
+ /**
+ * Translator that's used when none is specified. We want a GSON object that's
+ * configured the same way as it is in {@link GsonMessageBodyHandler}, so just get it
+ * from there.
+ */
+ private static final YamlJsonTranslator DEFAULT_TRANSLATOR =
+ new YamlJsonTranslator(new GsonMessageBodyHandler().getGson());
+
+ private final YamlJsonTranslator translator;
+
/**
* Constructs the object.
*/
public YamlMessageBodyHandler() {
+ this(DEFAULT_TRANSLATOR);
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param translator translator to use to translate to/from YAML
+ */
+ public YamlMessageBodyHandler(YamlJsonTranslator translator) {
logger.info("Accepting YAML for REST calls");
+ this.translator = translator;
}
@Override
@@ -75,10 +96,7 @@ public class YamlMessageBodyHandler implements MessageBodyReader<Object>, Messag
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) {
- new MyYamlCoder().encode(writer, object);
-
- } catch (CoderException e) {
- throw new IOException(e);
+ translator.toYaml(writer, object);
}
}
@@ -104,24 +122,10 @@ public class YamlMessageBodyHandler implements MessageBodyReader<Object>, Messag
try (InputStreamReader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) {
Class<?> clazz = (Class<?>) genericType;
- return new MyYamlCoder().decode(streamReader, clazz);
- }
- }
+ return translator.fromYaml(streamReader, clazz);
- /**
- * Yaml coder that yields YAMLException on input so that the http servlet can identify
- * it and generate a bad-request status code. Only the {@link #decode(Reader, Class)}
- * method must be overridden.
- */
- private static class MyYamlCoder extends StandardYamlCoder {
- @Override
- public <T> T decode(Reader source, Class<T> clazz) {
- try {
- return fromJson(source, clazz);
-
- } catch (JsonSyntaxException e) {
- throw new YAMLException(e);
- }
+ } catch (JsonSyntaxException e) {
+ throw new YAMLException(e);
}
}
}
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java
index 84f82f1a..6dee6f1f 100644
--- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java
@@ -39,6 +39,7 @@ import org.junit.Before;
import org.junit.Test;
import org.onap.policy.common.endpoints.http.server.HttpServletServer;
import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
import org.onap.policy.common.utils.coder.StandardYamlCoder;
import org.onap.policy.common.utils.gson.GsonTestUtils;
import org.onap.policy.common.utils.network.NetworkUtil;
@@ -51,7 +52,7 @@ import org.slf4j.LoggerFactory;
public class HttpServerTest {
private static final String LOCALHOST = "localhost";
private static final String JSON_MEDIA = "application/json";
- private static final String YAML_MEDIA = "application/yaml";
+ private static final String YAML_MEDIA = YamlMessageBodyHandler.APPLICATION_YAML;
private static final String SWAGGER_JSON = "/swagger.json";
private static final String JUNIT_ECHO_HELLO = "/junit/echo/hello";
private static final String JUNIT_ECHO_FULL_REQUEST = "/junit/echo/full/request";
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java
index 27ce300c..373950b2 100644
--- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java
@@ -32,6 +32,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
@Api(value = "echo")
@@ -56,7 +57,7 @@ public class RestEchoService {
@POST
@Path("/full/request")
- @Produces({MediaType.APPLICATION_JSON, "application/yaml"})
+ @Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
@ApiOperation(value = "echoes back the request structure", response = RestEchoReqResp.class)
public Response echoFullyPost(RestEchoReqResp reqResp) {
return Response.status(Status.OK).entity(reqResp).build();
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java
index cd40f012..519bbd1d 100644
--- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java
@@ -69,7 +69,6 @@ import org.onap.policy.common.utils.network.NetworkUtil;
import org.powermock.reflect.Whitebox;
public class RestServerTest {
- private static final String APPLICATION_YAML = "application/yaml";
private static final String SERVER1 = "my-server-A";
private static final String SERVER2 = "my-server-B";
private static final String FACTORY_FIELD = "factory";
@@ -247,8 +246,9 @@ public class RestServerTest {
public void testInvalidYaml() throws Exception {
initRealParams();
- assertEquals(200, roundTrip(new StandardCoder().encode(new MyRequest()), APPLICATION_YAML));
- assertEquals(400, roundTrip("<bogus yaml", APPLICATION_YAML));
+ assertEquals(200, roundTrip(new StandardCoder().encode(new MyRequest()),
+ YamlMessageBodyHandler.APPLICATION_YAML));
+ assertEquals(400, roundTrip("<bogus yaml", YamlMessageBodyHandler.APPLICATION_YAML));
assertThat(errorMsg).contains("Invalid request");
}
@@ -340,8 +340,8 @@ public class RestServerTest {
}
@Path("/")
- @Produces({MediaType.APPLICATION_JSON, APPLICATION_YAML})
- @Consumes({MediaType.APPLICATION_JSON, APPLICATION_YAML})
+ @Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
+ @Consumes({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
public static class RealProvider {
@POST
@Path("/request")
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlJacksonHandlerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlJacksonHandlerTest.java
new file mode 100644
index 00000000..7ca131ec
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlJacksonHandlerTest.java
@@ -0,0 +1,172 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.endpoints.http.server.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.JsonObject;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import javax.ws.rs.core.MediaType;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.http.server.YamlJacksonHandler;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+import org.onap.policy.common.gson.annotation.GsonJsonAnyGetter;
+import org.onap.policy.common.gson.annotation.GsonJsonAnySetter;
+
+public class YamlJacksonHandlerTest {
+
+ @Test
+ public void test() throws Exception {
+ YamlJacksonHandler hdlr = new YamlJacksonHandler();
+
+ assertTrue(hdlr.isReadable(null, null, null, MediaType.valueOf(YamlMessageBodyHandler.APPLICATION_YAML)));
+ assertFalse(hdlr.isReadable(null, null, null, MediaType.TEXT_PLAIN_TYPE));
+
+ JsonObject expected = new JsonObject();
+ expected.addProperty("myId", 100);
+ expected.addProperty("value", "a value");
+ expected.addProperty("abc", "def");
+ expected.addProperty("hello", "world");
+
+ Data data = new Data();
+ data.id = 10;
+ data.value = "a value";
+ data.props = new HashMap<>();
+ data.props.put("abc", "def");
+ data.props.put("hello", "world");
+
+ /*
+ * Ensure everything serializes as expected.
+ */
+ ByteArrayOutputStream outstr = new ByteArrayOutputStream();
+ hdlr.writeTo(data, Data.class, Data.class, null, null, null, outstr);
+
+ assertEquals("abc: def\nhello: world\nmyId: 100\nvalue: a value\n", outstr.toString("UTF-8"));
+
+ /*
+ * Ensure everything deserializes as expected.
+ */
+ Data data2 = (Data) hdlr.readFrom(Object.class, Data.class, null, null, null,
+ new ByteArrayInputStream(outstr.toByteArray()));
+
+ // id is not serialized, so we must copy it manually before comparing
+ data2.id = data.id;
+
+ assertEquals(data.toString(), data2.toString());
+ }
+
+ @Test
+ public void testMapDouble() throws Exception {
+ MyMap map = new MyMap();
+ map.props = new HashMap<>();
+ map.props.put("plainString", "def");
+ map.props.put("negInt", -10);
+ map.props.put("doubleVal", 12.5);
+ map.props.put("posLong", 100000000000L);
+
+ YamlJacksonHandler hdlr = new YamlJacksonHandler();
+ ByteArrayOutputStream outstr = new ByteArrayOutputStream();
+ hdlr.writeTo(map, map.getClass(), map.getClass(), null, null, null, outstr);
+
+ Object obj2 = hdlr.readFrom(Object.class, map.getClass(), null, null, null,
+ new ByteArrayInputStream(outstr.toByteArray()));
+ assertEquals(map.toString(), obj2.toString());
+
+ map = (MyMap) obj2;
+
+ assertEquals(-10, map.props.get("negInt"));
+ assertEquals(100000000000L, map.props.get("posLong"));
+ assertEquals(12.5, map.props.get("doubleVal"));
+ }
+
+ /**
+ * This class includes all policy-specific gson annotations.
+ */
+ public static class Data {
+ protected int id;
+
+ protected String value;
+
+ protected Map<String, String> props;
+
+ public int getMyId() {
+ return 100;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @GsonJsonAnyGetter
+ public Map<String, String> getProps() {
+ return props;
+ }
+
+ /**
+ * Sets a property.
+ *
+ * @param name property name
+ * @param value new value
+ */
+ @GsonJsonAnySetter
+ public void setProperty(String name, String value) {
+ if (props == null) {
+ props = new TreeMap<>();
+ }
+
+ props.put(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return "Data [id=" + id + ", value=" + value + ", props=" + props + "]";
+ }
+ }
+
+ private static class MyMap {
+ private Map<String, Object> props;
+
+ @Override
+ public String toString() {
+ return props.toString();
+ }
+
+ @SuppressWarnings("unused")
+ public Map<String, Object> getProps() {
+ return props;
+ }
+
+ @SuppressWarnings("unused")
+ public void setProps(Map<String, Object> props) {
+ this.props = props;
+ }
+ }
+}
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java
index 0ddad0bf..70b620c0 100644
--- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java
@@ -117,7 +117,7 @@ public class YamlMessageBodyHandlerTest {
MyObject obj1 = new MyObject(10);
assertThatThrownBy(() -> hdlr.writeTo(obj1, obj1.getClass(), CLASS_OBJ, null, null, null, outstr))
- .isInstanceOf(IOException.class);
+ .isInstanceOf(YAMLException.class);
outstr.close();
}
diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java
index d3d69812..c3f2d993 100644
--- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java
+++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardCoder.java
@@ -38,6 +38,8 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
+import lombok.AccessLevel;
+import lombok.Getter;
import org.onap.policy.common.gson.DoubleConverter;
import org.onap.policy.common.gson.MapDoubleAdapterFactory;
@@ -49,6 +51,7 @@ public class StandardCoder implements Coder {
/**
* Gson object used to encode and decode messages.
*/
+ @Getter(AccessLevel.PROTECTED)
private static final Gson GSON =
new GsonBuilder().registerTypeAdapter(StandardCoderObject.class, new StandardTypeAdapter())
.registerTypeAdapterFactory(new MapDoubleAdapterFactory()).create();
diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java
index 357b106e..36f15b96 100644
--- a/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java
+++ b/utils/src/main/java/org/onap/policy/common/utils/coder/StandardYamlCoder.java
@@ -20,245 +20,40 @@
package org.onap.policy.common.utils.coder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonNull;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.io.IOException;
import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map.Entry;
-import org.yaml.snakeyaml.DumperOptions;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.emitter.Emitter;
-import org.yaml.snakeyaml.error.YAMLException;
-import org.yaml.snakeyaml.nodes.MappingNode;
-import org.yaml.snakeyaml.nodes.Node;
-import org.yaml.snakeyaml.nodes.NodeTuple;
-import org.yaml.snakeyaml.nodes.ScalarNode;
-import org.yaml.snakeyaml.nodes.SequenceNode;
-import org.yaml.snakeyaml.nodes.Tag;
-import org.yaml.snakeyaml.resolver.Resolver;
-import org.yaml.snakeyaml.serializer.Serializer;
/**
* YAML encoder and decoder using the "standard" mechanism, which is currently gson. All
* of the methods perform conversion to/from YAML (instead of JSON).
*/
public class StandardYamlCoder extends StandardCoder {
+ private final YamlJsonTranslator translator;
/**
* Constructs the object.
*/
public StandardYamlCoder() {
- super();
+ translator = new YamlJsonTranslator(getGSON());
}
@Override
protected String toJson(Object object) {
- StringWriter output = new StringWriter();
- toJson(output, object);
- return output.toString();
+ return translator.toYaml(object);
}
@Override
protected void toJson(Writer target, Object object) {
- DumperOptions dumper = new DumperOptions();
- Serializer serializer = new Serializer(new Emitter(target, dumper), new Resolver(), dumper, null);
-
- try {
- serializer.open();
- serializer.serialize(makeYaml(toJsonTree(object)));
- serializer.close();
-
- } catch (IOException e) {
- throw new YAMLException(e);
- }
+ translator.toYaml(target, object);
}
@Override
protected <T> T fromJson(String yaml, Class<T> clazz) {
- Node node = new Yaml().compose(new StringReader(yaml));
- return fromJson(makeGson(node), clazz);
+ return translator.fromYaml(yaml, clazz);
}
@Override
protected <T> T fromJson(Reader source, Class<T> clazz) {
- Node node = new Yaml().compose(source);
- return fromJson(makeGson(node), clazz);
- }
-
- /**
- * Converts an arbitrary gson element into a corresponding Yaml node.
- *
- * @param jel gson element to be converted
- * @return a yaml node corresponding to the element
- */
- private Node makeYaml(JsonElement jel) {
- if (jel.isJsonArray()) {
- return makeYamlSequence((JsonArray) jel);
-
- } else if (jel.isJsonObject()) {
- return makeYamlMap((JsonObject) jel);
-
- } else if (jel.isJsonPrimitive()) {
- return makeYamlPrim((JsonPrimitive) jel);
-
- } else {
- return new ScalarNode(Tag.NULL, "", null, null, DumperOptions.ScalarStyle.PLAIN);
- }
- }
-
- /**
- * Converts an arbitrary gson array into a corresponding Yaml sequence.
- *
- * @param jel gson element to be converted
- * @return a yaml node corresponding to the element
- */
- private Node makeYamlSequence(JsonArray jel) {
- List<Node> nodes = new ArrayList<>(jel.size());
- jel.forEach(item -> nodes.add(makeYaml(item)));
-
- return new SequenceNode(Tag.SEQ, true, nodes, null, null, DumperOptions.FlowStyle.AUTO);
- }
-
- /**
- * Converts an arbitrary gson object into a corresponding Yaml map.
- *
- * @param jel gson element to be converted
- * @return a yaml node corresponding to the element
- */
- private Node makeYamlMap(JsonObject jel) {
- List<NodeTuple> nodes = new ArrayList<>(jel.size());
-
- for (Entry<String, JsonElement> entry : jel.entrySet()) {
- Node key = new ScalarNode(Tag.STR, entry.getKey(), null, null, DumperOptions.ScalarStyle.PLAIN);
- Node value = makeYaml(entry.getValue());
-
- nodes.add(new NodeTuple(key, value));
- }
-
- return new MappingNode(Tag.MAP, true, nodes, null, null, DumperOptions.FlowStyle.AUTO);
- }
-
- /**
- * Converts an arbitrary gson primitive into a corresponding Yaml scalar.
- *
- * @param jel gson element to be converted
- * @return a yaml node corresponding to the element
- */
- private Node makeYamlPrim(JsonPrimitive jel) {
- Tag tag;
- if (jel.isNumber()) {
- Class<? extends Number> clazz = jel.getAsNumber().getClass();
-
- if (clazz == Double.class || clazz == Float.class) {
- tag = Tag.FLOAT;
-
- } else {
- tag = Tag.INT;
- }
-
- } else if (jel.isBoolean()) {
- tag = Tag.BOOL;
-
- } else {
- // treat anything else as a string
- tag = Tag.STR;
- }
-
- return new ScalarNode(tag, jel.getAsString(), null, null, DumperOptions.ScalarStyle.PLAIN);
- }
-
- /**
- * Converts an arbitrary Yaml node into a corresponding gson element.
- *
- * @param node node to be converted
- * @return a gson element corresponding to the node
- */
- private JsonElement makeGson(Node node) {
- if (node instanceof MappingNode) {
- return makeGsonObject((MappingNode) node);
-
- } else if (node instanceof SequenceNode) {
- return makeGsonArray((SequenceNode) node);
-
- } else {
- return makeGsonPrim((ScalarNode) node);
- }
-
- // yaml doesn't appear to use anchor nodes when decoding so ignore them for now
- }
-
- /**
- * Converts a Yaml sequence into a corresponding gson array.
- *
- * @param node node to be converted
- * @return a gson element corresponding to the node
- */
- private JsonElement makeGsonArray(SequenceNode node) {
- List<Node> nodes = node.getValue();
-
- JsonArray array = new JsonArray(nodes.size());
- nodes.forEach(subnode -> array.add(makeGson(subnode)));
-
- return array;
- }
-
- /**
- * Converts a Yaml map into a corresponding gson object.
- *
- * @param node node to be converted
- * @return a gson element corresponding to the node
- */
- private JsonElement makeGsonObject(MappingNode node) {
- JsonObject obj = new JsonObject();
-
- for (NodeTuple tuple : node.getValue()) {
- Node key = tuple.getKeyNode();
- String skey = ((ScalarNode) key).getValue();
-
- obj.add(skey, makeGson(tuple.getValueNode()));
- }
-
- return obj;
- }
-
- /**
- * Converts a Yaml scalar into a corresponding gson primitive.
- *
- * @param node node to be converted
- * @return a gson element corresponding to the node
- */
- private JsonElement makeGsonPrim(ScalarNode node) {
- try {
- Tag tag = node.getTag();
-
- if (tag == Tag.INT) {
- return new JsonPrimitive(Long.valueOf(node.getValue()));
-
- } else if (tag == Tag.FLOAT) {
- return new JsonPrimitive(Double.valueOf(node.getValue()));
-
- } else if (tag == Tag.BOOL) {
- return new JsonPrimitive(Boolean.valueOf(node.getValue()));
-
- } else if (tag == Tag.NULL) {
- return JsonNull.INSTANCE;
-
- } else {
- // treat anything else as a string
- return new JsonPrimitive(node.getValue());
- }
-
- } catch (NumberFormatException ex) {
- // just treat it as a string
- return new JsonPrimitive(node.getValue());
- }
+ return translator.fromYaml(source, clazz);
}
}
diff --git a/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java b/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java
new file mode 100644
index 00000000..906c9fdd
--- /dev/null
+++ b/utils/src/main/java/org/onap/policy/common/utils/coder/YamlJsonTranslator.java
@@ -0,0 +1,321 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.utils.coder;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.emitter.Emitter;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+import org.yaml.snakeyaml.nodes.ScalarNode;
+import org.yaml.snakeyaml.nodes.SequenceNode;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.resolver.Resolver;
+import org.yaml.snakeyaml.serializer.Serializer;
+
+/**
+ * YAML-JSON translator. The methods may throw either of the runtime exceptions,
+ * YAMLException or JsonSyntaxException.
+ */
+public class YamlJsonTranslator {
+
+ /**
+ * Object to be used to translate between YAML and JsonElement.
+ */
+ private final Gson gson;
+
+ /**
+ * Constructs the object.
+ */
+ public YamlJsonTranslator() {
+ this(new Gson());
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param gson the Gson object to be used to serialize and de-serialize
+ */
+ public YamlJsonTranslator(Gson gson) {
+ this.gson = gson;
+ }
+
+ /**
+ * Translates a POJO into a YAML String.
+ *
+ * @param object POJO to be translated
+ * @return YAML representing the original object
+ */
+ public String toYaml(Object object) {
+ StringWriter output = new StringWriter();
+ toYaml(output, object);
+ return output.toString();
+ }
+
+ /**
+ * Serializes a POJO to a writer, as YAML.
+ *
+ * @param target target writer
+ * @param object POJO to be translated
+ */
+ public void toYaml(Writer target, Object object) {
+ DumperOptions dumper = new DumperOptions();
+ Serializer serializer = new Serializer(new Emitter(target, dumper), new Resolver(), dumper, null);
+
+ try {
+ serializer.open();
+ serializer.serialize(makeYaml(toJsonTree(object)));
+ serializer.close();
+
+ } catch (IOException e) {
+ throw new YAMLException(e);
+ }
+ }
+
+ /**
+ * Translates a POJO into a JsonElement.
+ *
+ * @param object POJO to be translated
+ * @return a JsonElement representing the original object
+ */
+ protected JsonElement toJsonTree(Object object) {
+ return gson.toJsonTree(object);
+ }
+
+ /**
+ * Translates a YAML string to a POJO.
+ *
+ * @param yaml YAML string to be translated
+ * @param clazz class of POJO to be created
+ * @return a POJO representing the original YAML
+ */
+ public <T> T fromYaml(String yaml, Class<T> clazz) {
+ return fromYaml(new StringReader(yaml), clazz);
+ }
+
+ /**
+ * Translates a YAML string, read from a reader, into a POJO.
+ *
+ * @param source source of the YAML string to be translated
+ * @param clazz class of POJO to be created
+ * @return a POJO representing the YAML read from the reader
+ */
+ public <T> T fromYaml(Reader source, Class<T> clazz) {
+ Node node = new Yaml().compose(source);
+ return fromJson(makeJson(node), clazz);
+ }
+
+ /**
+ * Translates a JsonElement to a POJO of the given class.
+ *
+ * @param jel element to be translated
+ * @param clazz class of POJO to be created
+ * @return a POJO representing the original element
+ */
+ protected <T> T fromJson(JsonElement jel, Class<T> clazz) {
+ return gson.fromJson(jel, clazz);
+ }
+
+ /**
+ * Converts an arbitrary gson element into a corresponding Yaml node.
+ *
+ * @param jel gson element to be converted
+ * @return a yaml node corresponding to the element
+ */
+ protected Node makeYaml(JsonElement jel) {
+ if (jel.isJsonArray()) {
+ return makeYamlSequence((JsonArray) jel);
+
+ } else if (jel.isJsonObject()) {
+ return makeYamlMap((JsonObject) jel);
+
+ } else if (jel.isJsonPrimitive()) {
+ return makeYamlPrim((JsonPrimitive) jel);
+
+ } else {
+ return new ScalarNode(Tag.NULL, "", null, null, DumperOptions.ScalarStyle.PLAIN);
+ }
+ }
+
+ /**
+ * Converts an arbitrary gson array into a corresponding Yaml sequence.
+ *
+ * @param jel gson element to be converted
+ * @return a yaml node corresponding to the element
+ */
+ protected SequenceNode makeYamlSequence(JsonArray jel) {
+ List<Node> nodes = new ArrayList<>(jel.size());
+ jel.forEach(item -> nodes.add(makeYaml(item)));
+
+ return new SequenceNode(Tag.SEQ, true, nodes, null, null, DumperOptions.FlowStyle.AUTO);
+ }
+
+ /**
+ * Converts an arbitrary gson object into a corresponding Yaml map.
+ *
+ * @param jel gson element to be converted
+ * @return a yaml node corresponding to the element
+ */
+ protected MappingNode makeYamlMap(JsonObject jel) {
+ List<NodeTuple> nodes = new ArrayList<>(jel.size());
+
+ for (Entry<String, JsonElement> entry : jel.entrySet()) {
+ Node key = new ScalarNode(Tag.STR, entry.getKey(), null, null, DumperOptions.ScalarStyle.PLAIN);
+ Node value = makeYaml(entry.getValue());
+
+ nodes.add(new NodeTuple(key, value));
+ }
+
+ return new MappingNode(Tag.MAP, true, nodes, null, null, DumperOptions.FlowStyle.AUTO);
+ }
+
+ /**
+ * Converts an arbitrary gson primitive into a corresponding Yaml scalar.
+ *
+ * @param jel gson element to be converted
+ * @return a yaml node corresponding to the element
+ */
+ protected ScalarNode makeYamlPrim(JsonPrimitive jel) {
+ Tag tag;
+ if (jel.isNumber()) {
+ Class<? extends Number> clazz = jel.getAsNumber().getClass();
+
+ if (clazz == Double.class || clazz == Float.class) {
+ tag = Tag.FLOAT;
+
+ } else {
+ tag = Tag.INT;
+ }
+
+ } else if (jel.isBoolean()) {
+ tag = Tag.BOOL;
+
+ } else {
+ // treat anything else as a string
+ tag = Tag.STR;
+ }
+
+ return new ScalarNode(tag, jel.getAsString(), null, null, DumperOptions.ScalarStyle.PLAIN);
+ }
+
+ /**
+ * Converts an arbitrary Yaml node into a corresponding gson element.
+ *
+ * @param node node to be converted
+ * @return a gson element corresponding to the node
+ */
+ protected JsonElement makeJson(Node node) {
+ if (node instanceof MappingNode) {
+ return makeJsonObject((MappingNode) node);
+
+ } else if (node instanceof SequenceNode) {
+ return makeJsonArray((SequenceNode) node);
+
+ } else {
+ return makeJsonPrim((ScalarNode) node);
+ }
+
+ // yaml doesn't appear to use anchor nodes when decoding so ignore them for now
+ }
+
+ /**
+ * Converts a Yaml sequence into a corresponding gson array.
+ *
+ * @param node node to be converted
+ * @return a gson element corresponding to the node
+ */
+ protected JsonArray makeJsonArray(SequenceNode node) {
+ List<Node> nodes = node.getValue();
+
+ JsonArray array = new JsonArray(nodes.size());
+ nodes.forEach(subnode -> array.add(makeJson(subnode)));
+
+ return array;
+ }
+
+ /**
+ * Converts a Yaml map into a corresponding gson object.
+ *
+ * @param node node to be converted
+ * @return a gson element corresponding to the node
+ */
+ protected JsonObject makeJsonObject(MappingNode node) {
+ JsonObject obj = new JsonObject();
+
+ for (NodeTuple tuple : node.getValue()) {
+ Node key = tuple.getKeyNode();
+ String skey = ((ScalarNode) key).getValue();
+
+ obj.add(skey, makeJson(tuple.getValueNode()));
+ }
+
+ return obj;
+ }
+
+ /**
+ * Converts a Yaml scalar into a corresponding gson primitive.
+ *
+ * @param node node to be converted
+ * @return a gson element corresponding to the node
+ */
+ protected JsonElement makeJsonPrim(ScalarNode node) {
+ try {
+ Tag tag = node.getTag();
+
+ if (tag == Tag.INT) {
+ return new JsonPrimitive(Long.valueOf(node.getValue()));
+
+ } else if (tag == Tag.FLOAT) {
+ return new JsonPrimitive(Double.valueOf(node.getValue()));
+
+ } else if (tag == Tag.BOOL) {
+ return new JsonPrimitive(Boolean.valueOf(node.getValue()));
+
+ } else if (tag == Tag.NULL) {
+ return JsonNull.INSTANCE;
+
+ } else {
+ // treat anything else as a string
+ return new JsonPrimitive(node.getValue());
+ }
+
+ } catch (NumberFormatException ex) {
+ // just treat it as a string
+ return new JsonPrimitive(node.getValue());
+ }
+ }
+}
diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java
index 2992933f..2a70f85a 100644
--- a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java
+++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardCoderTest.java
@@ -44,6 +44,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
@@ -201,6 +202,22 @@ public class StandardCoderTest {
}
@Test
+ public void testToJsonTree_testFromJsonJsonElementClassT() throws Exception {
+ MyMap map = new MyMap();
+ map.props = new LinkedHashMap<>();
+ map.props.put("jel keyA", "jel valueA");
+ map.props.put("jel keyB", "jel valueB");
+
+ JsonElement json = coder.toJsonTree(map);
+ assertEquals("{'props':{'jel keyA':'jel valueA','jel keyB':'jel valueB'}}".replace('\'', '"'), json.toString());
+
+ Object result = coder.fromJson(json, MyMap.class);
+
+ assertNotNull(result);
+ assertEquals("{jel keyA=jel valueA, jel keyB=jel valueB}", result.toString());
+ }
+
+ @Test
public void testConvertFromDouble() throws Exception {
String text = "[listA, {keyA=100}, 200]";
assertEquals(text, coder.decode(text, Object.class).toString());
@@ -276,7 +293,12 @@ public class StandardCoderTest {
}
}
- private static class MyMap {
+ public static class MyMap {
private Map<String, Object> props;
+
+ @Override
+ public String toString() {
+ return props.toString();
+ }
}
}
diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java
index 6ec20663..e38c5c9c 100644
--- a/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java
+++ b/utils/src/test/java/org/onap/policy/common/utils/coder/StandardYamlCoderTest.java
@@ -20,26 +20,20 @@
package org.onap.policy.common.utils.coder;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
+import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
-import java.util.List;
-import java.util.Map;
-import lombok.EqualsAndHashCode;
import org.junit.Before;
import org.junit.Test;
+import org.onap.policy.common.utils.coder.YamlJsonTranslatorTest.Container;
public class StandardYamlCoderTest {
private static final File YAML_FILE =
- new File("src/test/resources/org/onap/policy/common/utils/coder/StandardYamlCoder.yaml");
+ new File("src/test/resources/org/onap/policy/common/utils/coder/YamlJsonTranslator.yaml");
private StandardYamlCoder coder;
private Container cont;
@@ -59,30 +53,13 @@ public class StandardYamlCoderTest {
}
@Test
- public void testToJsonWriterObject() throws Exception {
- IOException ex = new IOException("expected exception");
+ public void testToJsonWriterObject() throws CoderException {
+ StringWriter wtr = new StringWriter();
+ coder.encode(wtr, cont);
+ String yaml = wtr.toString();
- // writer that throws an exception when the write() method is invoked
- Writer wtr = new Writer() {
- @Override
- public void write(char[] cbuf, int off, int len) throws IOException {
- throw ex;
- }
-
- @Override
- public void flush() throws IOException {
- // do nothing
- }
-
- @Override
- public void close() throws IOException {
- // do nothing
- }
- };
-
- assertThatThrownBy(() -> coder.encode(wtr, cont)).isInstanceOf(CoderException.class);
-
- wtr.close();
+ Container cont2 = coder.decode(yaml, Container.class);
+ assertEquals(cont, cont2);
}
@Test
@@ -94,58 +71,15 @@ public class StandardYamlCoderTest {
@Test
public void testFromJsonReaderClassOfT() {
- assertNotNull(cont.item);
- assertTrue(cont.item.boolVal);
- assertEquals(1000L, cont.item.longVal);
- assertEquals(1010.1f, cont.item.floatVal, 0.00001);
-
- assertEquals(4, cont.list.size());
- assertNull(cont.list.get(1));
-
- assertEquals(20, cont.list.get(0).intVal);
- assertEquals("string 30", cont.list.get(0).stringVal);
- assertNull(cont.list.get(0).nullVal);
-
- assertEquals(40.0, cont.list.get(2).doubleVal, 0.000001);
- assertNull(cont.list.get(2).nullVal);
- assertNotNull(cont.list.get(2).another);
- assertEquals(50, cont.list.get(2).another.intVal);
-
- assertTrue(cont.list.get(3).boolVal);
-
- assertNotNull(cont.map);
- assertEquals(3, cont.map.size());
-
- assertNotNull(cont.map.get("itemA"));
- assertEquals("stringA", cont.map.get("itemA").stringVal);
-
- assertNotNull(cont.map.get("itemB"));
- assertEquals("stringB", cont.map.get("itemB").stringVal);
-
- double dbl = 123456789012345678901234567890.0;
- assertEquals(dbl, cont.map.get("itemB").doubleVal, 1000.0);
-
- assertNotNull(cont.map.get("itemC"));
- assertTrue(cont.map.get("itemC").boolVal);
+ YamlJsonTranslatorTest.verify(cont);
}
-
- @EqualsAndHashCode
- public static class Container {
- private Item item;
- private List<Item> list;
- private Map<String, Item> map;
- }
-
- @EqualsAndHashCode
- public static class Item {
- private boolean boolVal;
- private int intVal;
- private long longVal;
- private double doubleVal;
- private float floatVal;
- private String stringVal;
- private Object nullVal;
- private Item another;
+ @Test
+ public void testStandardTypeAdapter() throws Exception {
+ String yaml = "abc: def\n";
+ StandardCoderObject sco = coder.fromJson(yaml, StandardCoderObject.class);
+ assertNotNull(sco.getData());
+ assertEquals("{'abc':'def'}".replace('\'', '"'), sco.getData().toString());
+ assertEquals(yaml, coder.toJson(sco));
}
}
diff --git a/utils/src/test/java/org/onap/policy/common/utils/coder/YamlJsonTranslatorTest.java b/utils/src/test/java/org/onap/policy/common/utils/coder/YamlJsonTranslatorTest.java
new file mode 100644
index 00000000..c76b775a
--- /dev/null
+++ b/utils/src/test/java/org/onap/policy/common/utils/coder/YamlJsonTranslatorTest.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.utils.coder;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.Map;
+import lombok.EqualsAndHashCode;
+import org.junit.Before;
+import org.junit.Test;
+import org.yaml.snakeyaml.error.YAMLException;
+
+public class YamlJsonTranslatorTest {
+ private static final File YAML_FILE =
+ new File("src/test/resources/org/onap/policy/common/utils/coder/YamlJsonTranslator.yaml");
+
+ private Container cont;
+ private YamlJsonTranslator translator;
+
+ /**
+ * Creates {@link #translator} and uses it to load {@link #cont}.
+ *
+ * @throws IOException if an error occurs
+ */
+ @Before
+ public void setUp() throws IOException {
+ translator = new YamlJsonTranslator();
+
+ try (FileReader rdr = new FileReader(YAML_FILE)) {
+ cont = translator.fromYaml(rdr, Container.class);
+ }
+ }
+
+ @Test
+ public void testToYamlObject() {
+ String yaml = translator.toYaml(cont);
+
+ Container cont2 = translator.fromYaml(yaml, Container.class);
+ assertEquals(cont, cont2);
+ }
+
+ @Test
+ public void testToYamlWriterObject() throws IOException {
+ IOException ex = new IOException("expected exception");
+
+ // writer that throws an exception when the write() method is invoked
+ Writer wtr = new Writer() {
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ throw ex;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ // do nothing
+ }
+
+ @Override
+ public void close() throws IOException {
+ // do nothing
+ }
+ };
+
+ assertThatThrownBy(() -> translator.toYaml(wtr, cont)).isInstanceOf(YAMLException.class);
+
+ wtr.close();
+ }
+
+ @Test
+ public void testFromYamlStringClassOfT() throws IOException {
+ String yaml = new String(Files.readAllBytes(YAML_FILE.toPath()), StandardCharsets.UTF_8);
+ Container cont2 = translator.fromYaml(yaml, Container.class);
+ assertEquals(cont, cont2);
+ }
+
+ @Test
+ public void testFromYamlReaderClassOfT() {
+ verify(cont);
+ }
+
+ /**
+ * Verifies that the container has contents matching the yaml file.
+ *
+ * @param container container whose contents are to be verified
+ */
+ public static void verify(Container container) {
+ assertNotNull(container.item);
+ assertTrue(container.item.boolVal);
+ assertEquals(1000L, container.item.longVal);
+ assertEquals(1010.1f, container.item.floatVal, 0.00001);
+
+ assertEquals(4, container.list.size());
+ assertNull(container.list.get(1));
+
+ assertEquals(20, container.list.get(0).intVal);
+ assertEquals("string 30", container.list.get(0).stringVal);
+ assertNull(container.list.get(0).nullVal);
+
+ assertEquals(40.0, container.list.get(2).doubleVal, 0.000001);
+ assertNull(container.list.get(2).nullVal);
+ assertNotNull(container.list.get(2).another);
+ assertEquals(50, container.list.get(2).another.intVal);
+
+ assertTrue(container.list.get(3).boolVal);
+
+ assertNotNull(container.map);
+ assertEquals(3, container.map.size());
+
+ assertNotNull(container.map.get("itemA"));
+ assertEquals("stringA", container.map.get("itemA").stringVal);
+
+ assertNotNull(container.map.get("itemB"));
+ assertEquals("stringB", container.map.get("itemB").stringVal);
+
+ double dbl = 123456789012345678901234567890.0;
+ assertEquals(dbl, container.map.get("itemB").doubleVal, 1000.0);
+
+ assertNotNull(container.map.get("itemC"));
+ assertTrue(container.map.get("itemC").boolVal);
+ }
+
+
+ @EqualsAndHashCode
+ public static class Container {
+ protected Item item;
+ protected List<Item> list;
+ protected Map<String, Item> map;
+ }
+
+ @EqualsAndHashCode
+ public static class Item {
+ protected boolean boolVal;
+ protected int intVal;
+ protected long longVal;
+ protected double doubleVal;
+ protected float floatVal;
+ protected String stringVal;
+ protected Object nullVal;
+ protected Item another;
+ }
+}
diff --git a/utils/src/test/resources/org/onap/policy/common/utils/coder/StandardYamlCoder.yaml b/utils/src/test/resources/org/onap/policy/common/utils/coder/YamlJsonTranslator.yaml
index 1da7bfa3..1da7bfa3 100644
--- a/utils/src/test/resources/org/onap/policy/common/utils/coder/StandardYamlCoder.yaml
+++ b/utils/src/test/resources/org/onap/policy/common/utils/coder/YamlJsonTranslator.yaml