summaryrefslogtreecommitdiffstats
path: root/policy-endpoints/src
diff options
context:
space:
mode:
authorJim Hahn <jrh3@att.com>2019-09-09 16:51:32 -0400
committerJim Hahn <jrh3@att.com>2019-09-11 15:32:01 -0400
commit173c4dbea9a1175a6f18031a221bb701deeecaa7 (patch)
treecff8d6fc46b6096b551b075e489b406c50b61531 /policy-endpoints/src
parent216b2beaf25eba50e948374d07e92b6c0a02b7c9 (diff)
Create StandardYamlCoder
Created StandardYamlCoder which is like a StandardCoder, except that the original converts to/from JSON, while the new class converts to/from YAML. Also added YamlMessageBodyHandler and incorporated it into the http server so that it supports a media type of */yaml. Change-Id: Ibd83a9f6d355a330f63e435f2bb41affcf1947c2 Issue-ID: POLICY-2065 Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'policy-endpoints/src')
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java3
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java110
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java111
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/MyYamlProvider.java82
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestEchoService.java2
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java4
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java230
7 files changed, 522 insertions, 20 deletions
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java
index 2368c0b8..decf95f9 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java
@@ -99,7 +99,8 @@ public class RestServer extends ServiceManagerContainer {
props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_AAF_SUFFIX,
String.valueOf(restServerParameters.isAaf()));
props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
- String.join(",", GsonMessageBodyHandler.class.getName(), JsonExceptionMapper.class.getName()));
+ String.join(",", GsonMessageBodyHandler.class.getName(), YamlMessageBodyHandler.class.getName(),
+ JsonExceptionMapper.class.getName()));
return props;
}
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
new file mode 100644
index 00000000..ab09c1a6
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/YamlMessageBodyHandler.java
@@ -0,0 +1,110 @@
+/*
+ * ============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 java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provider that serializes and de-serializes JSON via gson.
+ */
+@Provider
+@Consumes(MediaType.WILDCARD)
+@Produces(MediaType.WILDCARD)
+public class YamlMessageBodyHandler implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+ public static final Logger logger = LoggerFactory.getLogger(YamlMessageBodyHandler.class);
+
+ /**
+ * Constructs the object.
+ */
+ public YamlMessageBodyHandler() {
+ logger.info("Accepting YAML for REST calls");
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return canHandle(mediaType);
+ }
+
+ @Override
+ public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return -1;
+ }
+
+ @Override
+ public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
+
+ try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) {
+ new StandardYamlCoder().encode(writer, object);
+
+ } catch (CoderException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return canHandle(mediaType);
+ }
+
+ /**
+ * Determines if this provider can handle the given media type.
+ *
+ * @param mediaType the media type of interest
+ * @return {@code true} if this provider handles the given media type, {@code false}
+ * otherwise
+ */
+ private boolean canHandle(MediaType mediaType) {
+ return (mediaType != null && "yaml".equalsIgnoreCase(mediaType.getSubtype()));
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
+
+ try (InputStreamReader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) {
+ Class<?> clazz = (Class<?>) genericType;
+ return new StandardYamlCoder().decode(streamReader, clazz);
+
+ } catch (CoderException e) {
+ throw new IOException(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 f2b53648..84f82f1a 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
@@ -26,9 +26,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.google.gson.Gson;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -40,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.utils.coder.StandardYamlCoder;
import org.onap.policy.common.utils.gson.GsonTestUtils;
import org.onap.policy.common.utils.network.NetworkUtil;
import org.slf4j.Logger;
@@ -50,6 +50,8 @@ 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 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";
@@ -84,6 +86,7 @@ public class HttpServerTest {
MyJacksonProvider.resetSome();
MyGsonProvider.resetSome();
+ MyYamlProvider.resetSome();
}
private static void incrementPort() {
@@ -112,7 +115,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
}
@@ -135,7 +138,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
assertTrue(MyJacksonProvider.hasReadSome());
@@ -143,6 +146,9 @@ public class HttpServerTest {
assertFalse(MyGsonProvider.hasReadSome());
assertFalse(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyYamlProvider.hasReadSome());
+ assertFalse(MyYamlProvider.hasWrittenSome());
}
@Test
@@ -164,7 +170,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
assertTrue(MyGsonProvider.hasReadSome());
@@ -172,6 +178,43 @@ public class HttpServerTest {
assertFalse(MyJacksonProvider.hasReadSome());
assertFalse(MyJacksonProvider.hasWrittenSome());
+
+ assertFalse(MyYamlProvider.hasReadSome());
+ assertFalse(MyYamlProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testYamlPackageServer() throws Exception {
+ logger.info("-- testYamlPackageServer() --");
+
+ HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
+ .build("echo", LOCALHOST, port, "/", false, true);
+
+ server.setSerializationProvider(MyYamlProvider.class.getName());
+ server.addServletPackage("/*", this.getClass().getPackage().getName());
+ server.addFilterClass("/*", TestFilter.class.getName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText(SOME_TEXT);
+ String reqText = new StandardYamlCoder().encode(request);
+
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
+
+ // response reader strips newlines, so we should, too, before comparing
+ assertEquals(reqText.replace("\n", ""), response);
+
+ assertTrue(MyYamlProvider.hasReadSome());
+ assertTrue(MyYamlProvider.hasWrittenSome());
+
+ assertFalse(MyGsonProvider.hasReadSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyJacksonProvider.hasReadSome());
+ assertFalse(MyJacksonProvider.hasWrittenSome());
}
@Test
@@ -191,7 +234,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
}
@@ -213,7 +256,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
assertTrue(MyJacksonProvider.hasReadSome());
@@ -221,6 +264,9 @@ public class HttpServerTest {
assertFalse(MyGsonProvider.hasReadSome());
assertFalse(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyYamlProvider.hasReadSome());
+ assertFalse(MyYamlProvider.hasWrittenSome());
}
@Test
@@ -241,7 +287,7 @@ public class HttpServerTest {
request.setText(SOME_TEXT);
String reqText = gson.toJson(request);
- String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, reqText);
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, JSON_MEDIA, reqText);
assertEquals(reqText, response);
assertTrue(MyGsonProvider.hasReadSome());
@@ -249,6 +295,42 @@ public class HttpServerTest {
assertFalse(MyJacksonProvider.hasReadSome());
assertFalse(MyJacksonProvider.hasWrittenSome());
+
+ assertFalse(MyYamlProvider.hasReadSome());
+ assertFalse(MyYamlProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testYamlClassServer() throws Exception {
+ logger.info("-- testYamlClassServer() --");
+
+ HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory()
+ .build("echo", LOCALHOST, port, "/", false, true);
+ server.setSerializationProvider(MyYamlProvider.class.getName());
+ server.addServletClass("/*", RestEchoService.class.getName());
+ server.addFilterClass("/*", TestFilter.class.getName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText(SOME_TEXT);
+ String reqText = new StandardYamlCoder().encode(request);
+
+ String response = http(portUrl + JUNIT_ECHO_FULL_REQUEST, YAML_MEDIA, reqText);
+
+ // response reader strips newlines, so we should, too, before comparing
+ assertEquals(reqText.replace("\n", ""), response);
+
+ assertTrue(MyYamlProvider.hasReadSome());
+ assertTrue(MyYamlProvider.hasWrittenSome());
+
+ assertFalse(MyGsonProvider.hasReadSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyJacksonProvider.hasReadSome());
+ assertFalse(MyJacksonProvider.hasWrittenSome());
}
@Test
@@ -416,7 +498,7 @@ public class HttpServerTest {
* @throws IOException thrown is IO exception occurs
* @throws InterruptedException thrown if thread interrupted occurs
*/
- private String http(String urlString, String post)
+ private String http(String urlString, String mediaType, String post)
throws IOException, InterruptedException {
URL url = new URL(urlString);
if (!NetworkUtil.isTcpPortOpen(url.getHost(), url.getPort(), 25, 2)) {
@@ -425,7 +507,7 @@ public class HttpServerTest {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
- conn.setRequestProperty("Content-Type", "application/json");
+ conn.setRequestProperty("Content-Type", mediaType);
IOUtils.write(post, conn.getOutputStream());
return response(conn);
}
@@ -438,14 +520,9 @@ public class HttpServerTest {
* @throws IOException if an I/O error occurs
*/
private String response(URLConnection conn) throws IOException {
- StringBuilder response = new StringBuilder();
- try (BufferedReader ioReader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
- String line;
- while ((line = ioReader.readLine()) != null) {
- response.append(line);
- }
+ try (InputStream inpstr = conn.getInputStream()) {
+ return String.join("", IOUtils.readLines(inpstr));
}
- return response.toString();
}
}
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/MyYamlProvider.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/MyYamlProvider.java
new file mode 100644
index 00000000..098ecb44
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/MyYamlProvider.java
@@ -0,0 +1,82 @@
+/*
+ * ============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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import lombok.AccessLevel;
+import lombok.Setter;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+
+/**
+ * YamlMessageBodyHandler that tracks activities.
+ */
+public class MyYamlProvider extends YamlMessageBodyHandler {
+
+ @Setter(AccessLevel.PRIVATE)
+ private static boolean readSome = false;
+
+ @Setter(AccessLevel.PRIVATE)
+ private static boolean wroteSome = false;
+
+ /**
+ * Constructs the object and resets the variables to indicate that no activity has
+ * occurred yet.
+ */
+ public MyYamlProvider() {
+ super();
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
+
+ setReadSome(true);
+ return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
+ }
+
+ @Override
+ public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
+
+ setWroteSome(true);
+ super.writeTo(object, type, genericType, annotations, mediaType, httpHeaders, entityStream);
+ }
+
+ public static boolean hasReadSome() {
+ return readSome;
+ }
+
+ public static boolean hasWrittenSome() {
+ return wroteSome;
+ }
+
+ public static void resetSome() {
+ MyYamlProvider.readSome = false;
+ MyYamlProvider.wroteSome = false;
+ }
+
+}
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 9db1053f..27ce300c 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
@@ -56,7 +56,7 @@ public class RestEchoService {
@POST
@Path("/full/request")
- @Produces(MediaType.APPLICATION_JSON)
+ @Produces({MediaType.APPLICATION_JSON, "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 fd9b59f7..ee28b96d 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
@@ -56,6 +56,7 @@ import org.onap.policy.common.endpoints.http.server.HttpServletServerFactory;
import org.onap.policy.common.endpoints.http.server.JsonExceptionMapper;
import org.onap.policy.common.endpoints.http.server.RestServer;
import org.onap.policy.common.endpoints.http.server.RestServer.Factory;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
import org.onap.policy.common.endpoints.http.server.aaf.AafAuthFilter;
import org.onap.policy.common.endpoints.parameters.RestServerParameters;
import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
@@ -211,7 +212,8 @@ public class RestServerTest {
assertEquals(PASS, props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX));
assertEquals("true", props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX));
assertEquals("true", props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_AAF_SUFFIX));
- assertEquals(String.join(",", GsonMessageBodyHandler.class.getName(), JsonExceptionMapper.class.getName()),
+ assertEquals(String.join(",", GsonMessageBodyHandler.class.getName(), YamlMessageBodyHandler.class.getName(),
+ JsonExceptionMapper.class.getName()),
props.getProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER));
}
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
new file mode 100644
index 00000000..b8963e9b
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/YamlMessageBodyHandlerTest.java
@@ -0,0 +1,230 @@
+/*
+ * ============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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import javax.ws.rs.core.MediaType;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+
+public class YamlMessageBodyHandlerTest {
+ private static final String EXPECTED_EXCEPTION = "expected exception";
+
+ private static final String GEN_TYPE = "some-type";
+ private static final String[] subtypes = {"yaml"};
+
+ @SuppressWarnings("rawtypes")
+ private static final Class GEN_CLASS = MyObject.class;
+
+ @SuppressWarnings("unchecked")
+ private static final Class<Object> CLASS_OBJ = GEN_CLASS;
+
+ private YamlMessageBodyHandler hdlr;
+
+ @Before
+ public void setUp() {
+ hdlr = new YamlMessageBodyHandler();
+ }
+
+ @Test
+ public void testIsWriteable() {
+ for (String subtype : subtypes) {
+ assertTrue("writeable " + subtype, hdlr.isWriteable(null, null, null, new MediaType(GEN_TYPE, subtype)));
+
+ }
+
+ // the remaining should be FALSE
+
+ // null media type
+ assertFalse(hdlr.isWriteable(null, null, null, null));
+
+ // null subtype
+ assertFalse(hdlr.isWriteable(null, null, null, new MediaType(GEN_TYPE, null)));
+
+ // text subtype
+ assertFalse(hdlr.isWriteable(null, null, null, MediaType.TEXT_HTML_TYPE));
+ }
+
+ @Test
+ public void testGetSize() {
+ assertEquals(-1, hdlr.getSize(null, null, null, null, null));
+ }
+
+ @Test
+ public void testWriteTo_testReadFrom() throws Exception {
+ ByteArrayOutputStream outstr = new ByteArrayOutputStream();
+ MyObject obj1 = new MyObject(10);
+ hdlr.writeTo(obj1, obj1.getClass(), CLASS_OBJ, null, null, null, outstr);
+
+ Object obj2 = hdlr.readFrom(CLASS_OBJ, CLASS_OBJ, null, null, null,
+ new ByteArrayInputStream(outstr.toByteArray()));
+ assertEquals(obj1.toString(), obj2.toString());
+ }
+
+ @Test
+ public void testWriteTo_DifferentTypes() throws Exception {
+ ByteArrayOutputStream outstr = new ByteArrayOutputStream();
+
+ // use a derived type, but specify the base type when writing
+ MyObject obj1 = new DerivedObject(10);
+ hdlr.writeTo(obj1, obj1.getClass(), CLASS_OBJ, null, null, null, outstr);
+
+ Object obj2 = hdlr.readFrom(CLASS_OBJ, CLASS_OBJ, null, null, null,
+ new ByteArrayInputStream(outstr.toByteArray()));
+ assertEquals(obj1.toString(), obj2.toString());
+ }
+
+ @Test
+ public void testWriteTo_Ex() throws Exception {
+ OutputStream outstr = new OutputStream() {
+ @Override
+ public void write(int value) throws IOException {
+ throw new IOException(EXPECTED_EXCEPTION);
+ }
+ };
+
+ MyObject obj1 = new MyObject(10);
+
+ assertThatThrownBy(() -> hdlr.writeTo(obj1, obj1.getClass(), CLASS_OBJ, null, null, null, outstr))
+ .isInstanceOf(IOException.class);
+
+ outstr.close();
+ }
+
+ @Test
+ public void testIsReadable() {
+ for (String subtype : subtypes) {
+ assertTrue("readable " + subtype, hdlr.isReadable(null, null, null, new MediaType(GEN_TYPE, subtype)));
+
+ }
+
+ // the remaining should be FALSE
+
+ // null media type
+ assertFalse(hdlr.isReadable(null, null, null, null));
+
+ // null subtype
+ assertFalse(hdlr.isReadable(null, null, null, new MediaType(GEN_TYPE, null)));
+
+ // text subtype
+ assertFalse(hdlr.isReadable(null, null, null, MediaType.TEXT_HTML_TYPE));
+ }
+
+ @Test
+ public void testReadFrom_DifferentTypes() throws Exception {
+ ByteArrayOutputStream outstr = new ByteArrayOutputStream();
+ MyObject obj1 = new MyObject(10);
+ hdlr.writeTo(obj1, obj1.getClass(), CLASS_OBJ, null, null, null, outstr);
+
+ // use a derived type, but specify the base type when reading
+ @SuppressWarnings("rawtypes")
+ Class clazz = DerivedObject.class;
+
+ @SuppressWarnings("unchecked")
+ Class<Object> objclazz = clazz;
+
+ Object obj2 = hdlr.readFrom(objclazz, CLASS_OBJ, null, null, null,
+ new ByteArrayInputStream(outstr.toByteArray()));
+ assertEquals(obj1.toString(), obj2.toString());
+ }
+
+ @Test
+ public void testReadFrom_Ex() throws Exception {
+ InputStream inpstr = new InputStream() {
+ @Override
+ public int read() throws IOException {
+ throw new IOException(EXPECTED_EXCEPTION);
+ }
+ };
+
+ assertThatThrownBy(() -> hdlr.readFrom(CLASS_OBJ, CLASS_OBJ, null, null, null, inpstr))
+ .isInstanceOf(IOException.class);
+
+ inpstr.close();
+ }
+
+ @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);
+
+ 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"));
+ }
+
+ public static class DerivedObject extends MyObject {
+ public DerivedObject(int id) {
+ super(id);
+ }
+ }
+
+ public static class MyObject {
+ private int id;
+
+ public MyObject() {
+ super();
+ }
+
+ public MyObject(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "MyObject [id=" + id + "]";
+ }
+ }
+
+ private static class MyMap {
+ private Map<String, Object> props;
+
+ @Override
+ public String toString() {
+ return props.toString();
+ }
+ }
+}