Added "provider" property to both http client and server builders.
The provider defaults to jackson, to maintain backward compatibility
until other policy code has been converted to gson.
Removed commented item from pom.
Added some comments and re-arranged a few pieces of code.
Fixed a few typos and removed spacing at the end of some lines.
Reordered imports.
Added comments about limitations when using jersey-media-json-jackson.
Address ridiculous checkstyle complaint.
Support comma-separated list of serialization providers in jersey client.
Disabled metainf discovery from jersey client and server so that the
media-json dependencies could be re-instated in the pom.
Address another ridiculous checkstyle complaint.
Change-Id: Ic5a93b475d0ee9b435352b3516de6b865b00a86a
Issue-ID: POLICY-1428
Signed-off-by: Jim Hahn <jrh3@att.com>
<artifactId>jersey-common</artifactId>
<version>${jersey.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
* policy-endpoints
* ================================================================================
* Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- * Modifications Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018-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.
private String clientName;
private String hostname;
private String basePath;
+ private String serializationProvider;
public static TopicParamsBuilder builder() {
return new TopicParamsBuilder();
return additionalProps != null;
}
+ public String getSerializationProvider() {
+ return serializationProvider;
+ }
+
public static class TopicParamsBuilder {
final BusTopicParams params = new BusTopicParams();
return this;
}
+ public TopicParamsBuilder serializationProvider(String serializationProvider) {
+ this.params.serializationProvider = serializationProvider;
+ return this;
+ }
+
}
}
* Build and http client with the following parameters.
*/
HttpClient build(BusTopicParams busTopicParams)
- throws KeyManagementException, NoSuchAlgorithmException;
+ throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException;
/**
* Build http client from properties.
@Override
public synchronized HttpClient build(BusTopicParams busTopicParams)
- throws KeyManagementException, NoSuchAlgorithmException {
+ throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
if (clients.containsKey(busTopicParams.getClientName())) {
return clients.get(busTopicParams.getClientName());
}
String password = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "."
+ clientName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX);
+ final String classProv = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES
+ + "." + clientName + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER);
+
String managedString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "."
+ clientName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX);
boolean managed = true;
.userName(userName)
.password(password)
.managed(managed)
+ .serializationProvider(classProv)
.build());
clientList.add(client);
} catch (Exception e) {
package org.onap.policy.common.endpoints.http.client.internal;
import com.fasterxml.jackson.annotation.JsonIgnore;
-
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;
-
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.core.Response;
-
+import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
import org.onap.policy.common.endpoints.http.client.HttpClient;
/**
* Http Client implementation using a Jersey Client.
+ *
+ * <p>Note: the serialization provider will be ignored if the maven artifact,
+ * <i>jersey-media-json-jackson</i>, is included, regardless of whether it's included
+ * directly or indirectly.
*/
public class JerseyClient implements HttpClient {
* Logger.
*/
private static Logger logger = LoggerFactory.getLogger(JerseyClient.class);
+
+ protected static final String JERSEY_DEFAULT_SERIALIZATION_PROVIDER =
+ "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider";
protected final String name;
protected final boolean https;
/**
* Constructor.
*
- * <p>name the name https is it https or not selfSignedCerts are there self signed certs hostname
- * the hostname port port being used basePath base context userName user password password
+ * <p>name the name https is it https or not selfSignedCerts are there self signed certs
+ * hostname the hostname port port being used basePath base context userName user
+ * password password
*
* @param busTopicParams Input parameters object
* @throws KeyManagementException key exception
* @throws NoSuchAlgorithmException no algorithm exception
+ * @throws ClassNotFoundException if the serialization provider cannot be found
*/
- public JerseyClient(BusTopicParams busTopicParams) throws KeyManagementException, NoSuchAlgorithmException {
+ public JerseyClient(BusTopicParams busTopicParams)
+ throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
super();
this.client.register(authFeature);
}
+ registerSerProviders(busTopicParams.getSerializationProvider());
+
+ this.client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+
this.baseUrl = tmpBaseUrl.append(this.hostname).append(":").append(this.port).append("/")
.append((this.basePath == null) ? "" : this.basePath).toString();
}
+ /**
+ * Registers the serialization provider(s) with the client.
+ *
+ * @param serializationProvider comma-separated list of serialization providers
+ * @throws ClassNotFoundException if the serialization provider cannot be found
+ */
+ private void registerSerProviders(String serializationProvider) throws ClassNotFoundException {
+ String providers = (serializationProvider == null || serializationProvider.isEmpty()
+ ? JERSEY_DEFAULT_SERIALIZATION_PROVIDER : serializationProvider);
+ for (String prov : providers.split(",")) {
+ this.client.register(Class.forName(prov));
+ }
+ }
+
@Override
public Response get(String path) {
if (path != null && !path.isEmpty()) {
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-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.
*/
boolean isAaf();
+ /**
+ * Sets the serialization provider to be used when classes are added to the service.
+ *
+ * @param provider the provider to use for message serialization and de-serialization
+ */
+ void setSerializationProvider(String provider);
+
/**
* Adds a filter at the specified path.
*
final String restUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES
+ "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX);
+ final String classProv = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES
+ + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER);
+
final String managedString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES
+ "." + serviceName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX);
boolean managed = true;
aaf = Boolean.parseBoolean(aafString);
}
+
HttpServletServer service = build(serviceName, https, hostName, servicePort, contextUriPath, swagger,
managed);
+ if (classProv != null && !classProv.isEmpty()) {
+ service.setSerializationProvider(classProv);
+ }
+
/* authentication method either AAF or HTTP Basic Auth */
if (aaf) {
--- /dev/null
+/*
+ * ============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.internal;
+
+import com.google.gson.Gson;
+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.WebApplicationException;
+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;
+
+/**
+ * Provider that serializes and de-serializes JSON via gson.
+ *
+ * <p>Note: <i>jersey</i> will ignore this class if the maven artifact,
+ * <i>jersey-media-json-jackson</i>, is included, regardless of whether it's included
+ * directly or indirectly.
+ */
+@Provider
+@Consumes(MediaType.WILDCARD)
+@Produces(MediaType.WILDCARD)
+public class GsonMessageBodyHandler implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+ /**
+ * Object to be used to serialize and de-serialize.
+ */
+ private Gson gson;
+
+ /**
+ * Constructs the object, using a plain Gson object.
+ */
+ public GsonMessageBodyHandler() {
+ this(new Gson());
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param gson the Gson object to be used to serialize and de-serialize
+ */
+ public GsonMessageBodyHandler(Gson gson) {
+ this.gson = gson;
+ }
+
+ @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, WebApplicationException {
+
+ try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) {
+ Type jsonType = (type.equals(genericType) ? type : genericType);
+ gson.toJson(object, jsonType, writer);
+ }
+ }
+
+ @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) {
+ if (mediaType == null) {
+ return true;
+ }
+
+ String subtype = mediaType.getSubtype();
+
+ return "json".equalsIgnoreCase(subtype) || subtype.endsWith("+json") || "javascript".equals(subtype)
+ || "x-javascript".equals(subtype) || "x-json".equals(subtype);
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+
+ try (InputStreamReader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) {
+ Type jsonType = (type.equals(genericType) ? type : genericType);
+ return gson.fromJson(streamReader, jsonType);
+ }
+ }
+}
* ============LICENSE_START=======================================================
* policy-endpoints
* ================================================================================
- * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-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.
import io.swagger.jersey.config.JerseyJaxrsConfig;
import java.util.HashMap;
import org.eclipse.jetty.servlet.ServletHolder;
+import org.glassfish.jersey.server.ServerProperties;
import org.onap.policy.common.utils.network.NetworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* REST Jetty Server that uses Jersey Servlets to support JAX-RS Web Services.
+ *
+ * <p>Note: the serialization provider will always be added to the server's class providers,
+ * as will the swagger providers (assuming swagger has been enabled). This happens whether
+ * {@link #addServletClass(String, String)} is used or
+ * {@link #addServletPackage(String, String)} is used. Thus it's possible to have both the
+ * server's class provider property and the server's package provider property populated.
+ *
+ * <p>Also note: the serialization provider will be ignored if the maven artifact,
+ * <i>jersey-media-json-jackson</i>, is included, regardless of whether it's included
+ * directly or indirectly.
*/
public class JettyJerseyServer extends JettyServletServer {
*/
protected static final String SWAGGER_PRETTY_PRINT = "swagger.pretty.print";
- /**
- * Swagger Packages.
- */
- protected static final String SWAGGER_INIT_PACKAGES_PARAM_VALUE = "io.swagger.jaxrs.listing";
-
- /**
- * Jersey Packages Init Param Name.
- */
- protected static final String JERSEY_INIT_PACKAGES_PARAM_NAME = "jersey.config.server.provider.packages";
-
- /**
- * Jersey Packages Init Param Value.
- */
- protected static final String JERSEY_INIT_PACKAGES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json";
-
- /**
- * Jersey Classes Init Param Name.
- */
- protected static final String JERSEY_INIT_CLASSNAMES_PARAM_NAME = "jersey.config.server.provider.classnames";
-
/**
* Jersey Jackson Classes Init Param Value.
*/
*/
protected String swaggerId = null;
+ /**
+ * The serialization provider to be used when classes are added to the service.
+ */
+ private String classProvider = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE;
+
/**
* Constructor.
- *
+ *
* @param name name
* @param https enable https?
* @param host host server host
* @param port port server port
* @param swagger support swagger?
* @param contextPath context path
- *
+ *
* @throws IllegalArgumentException in invalid arguments are provided
*/
public JettyJerseyServer(String name, boolean https, String host, int port, String contextPath, boolean swagger) {
/**
* Retrieves cached server based on servlet path.
- *
+ *
* @param servletPath servlet path
* @return the jetty servlet holder
- *
+ *
* @throws IllegalArgumentException if invalid arguments are provided
*/
protected synchronized ServletHolder getServlet(String servletPath) {
ServletHolder jerseyServlet = this.getServlet(servPath);
- String initClasses = jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
- if (initClasses != null && !initClasses.isEmpty()) {
- logger.warn("Both packages and classes are used in Jetty+Jersey Configuration: {}", restPackage);
- }
+ initStandardParams(jerseyServlet);
- String initPackages = jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
+ String initPackages = jerseyServlet.getInitParameter(ServerProperties.PROVIDER_PACKAGES);
if (initPackages == null) {
- if (this.swaggerId != null) {
- initPackages =
- JERSEY_INIT_PACKAGES_PARAM_VALUE + "," + SWAGGER_INIT_PACKAGES_PARAM_VALUE + "," + restPackage;
-
- jerseyServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
- jerseyServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
- } else {
- initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," + restPackage;
- }
+ initPackages = restPackage;
+
} else {
- initPackages = initPackages + "," + restPackage;
+ initPackages += "," + restPackage;
}
- jerseyServlet.setInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME, initPackages);
+ jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, initPackages);
if (logger.isDebugEnabled()) {
logger.debug("{}: added REST package: {}", this, jerseyServlet.dump());
ServletHolder jerseyServlet = this.getServlet(servletPath);
- String initPackages = jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
- if (initPackages != null && !initPackages.isEmpty()) {
- logger.warn("Both classes and packages are used in Jetty+Jersey Configuration: {}", restClass);
- }
+ initStandardParams(jerseyServlet);
- String initClasses = jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
+ String initClasses = jerseyServlet.getInitParameter(ServerProperties.PROVIDER_CLASSNAMES);
if (initClasses == null) {
- if (this.swaggerId != null) {
- initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + SWAGGER_INIT_CLASSNAMES_PARAM_VALUE
- + "," + restClass;
-
- jerseyServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
- jerseyServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
- } else {
- initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + restClass;
- }
+ initClasses = restClass;
+
} else {
- initClasses = initClasses + "," + restClass;
+ initClasses += "," + restClass;
}
- jerseyServlet.setInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME, initClasses);
+ jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, initClasses);
if (logger.isDebugEnabled()) {
logger.debug("{}: added REST class: {}", this, jerseyServlet.dump());
}
}
+ /**
+ * Adds "standard" parameters to the initParameter set. Sets swagger parameters, if
+ * specified, and sets the class provider property. This can be invoked multiple
+ * times, but only the first actually causes any changes to the parameter set.
+ *
+ * @param jerseyServlet servlet into which parameters should be added
+ */
+ private void initStandardParams(ServletHolder jerseyServlet) {
+ String initClasses = jerseyServlet.getInitParameter(ServerProperties.PROVIDER_CLASSNAMES);
+ if (initClasses != null) {
+ return;
+ }
+
+ initClasses = classProvider;
+
+ if (this.swaggerId != null) {
+ initClasses += "," + SWAGGER_INIT_CLASSNAMES_PARAM_VALUE;
+
+ jerseyServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
+ jerseyServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
+ }
+
+ jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, initClasses);
+
+ jerseyServlet.setInitParameter(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+ }
+
+ /**
+ * Note: this must be invoked <i>before</i> {@link #addServletClass(String, String)}
+ * or {@link #addServletPackage(String, String)}.
+ */
+ @Override
+ public void setSerializationProvider(String provider) {
+ classProvider = provider;
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
String PROPERTY_HTTP_HTTPS_SUFFIX = ".https";
String PROPERTY_HTTP_SWAGGER_SUFFIX = ".swagger";
+ String PROPERTY_HTTP_SERIALIZATION_PROVIDER = ".serialization.provider";
+
/* HTTP Client Properties */
String PROPERTY_HTTP_CLIENT_SERVICES = "http.client.services";
--- /dev/null
+/*
+ * ============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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import javax.ws.rs.core.MediaType;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.endpoints.http.server.internal.GsonMessageBodyHandler;
+
+public class GsonMessageBodyHandlerTest {
+ private static final String GEN_TYPE = "some-type";
+ private static final String[] subtypes = {"json", "jSoN", "hello+json", "javascript", "x-javascript", "x-json"};
+
+ @SuppressWarnings("rawtypes")
+ private static final Class GEN_CLASS = MyObject.class;
+
+ @SuppressWarnings("unchecked")
+ private static final Class<Object> CLASS_OBJ = GEN_CLASS;
+
+ private GsonMessageBodyHandler hdlr;
+
+ @Before
+ public void setUp() {
+ hdlr = new GsonMessageBodyHandler();
+ }
+
+ @Test
+ public void testIsWriteable() {
+ // null media type
+ assertTrue(hdlr.isWriteable(null, null, null, null));
+
+ for (String subtype : subtypes) {
+ assertTrue("writeable " + subtype, hdlr.isWriteable(null, null, null, new MediaType(GEN_TYPE, subtype)));
+
+ }
+
+ // the remaining should be FALSE
+
+ // 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 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 testIsReadable() {
+ // null media type
+ assertTrue(hdlr.isReadable(null, null, null, null));
+
+ // null subtype
+ assertFalse(hdlr.isReadable(null, null, null, new MediaType(GEN_TYPE, null)));
+
+ for (String subtype : subtypes) {
+ assertTrue("readable " + subtype, hdlr.isReadable(null, null, null, new MediaType(GEN_TYPE, subtype)));
+
+ }
+
+ // the remaining should be FALSE
+
+ // 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 = new MyObject() {}.getClass();
+
+ @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());
+ }
+
+ 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 + "]";
+ }
+ }
+
+}
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 java.io.IOException;
import java.security.KeyManagementException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
* @throws IOException can have an IO exception
*/
@BeforeClass
- public static void setUp() throws InterruptedException, IOException {
+ public static void setUpBeforeClass() throws InterruptedException, IOException {
/* echo server - http + no auth */
final HttpServletServer echoServerNoAuth =
}
}
+ /**
+ * Clear https clients and reset providers.
+ */
+ @Before
+ public void setUp() {
+ HttpClient.factory.destroy();
+
+ MyGsonProvider.resetSome();
+ MyJacksonProvider.resetSome();
+ }
+
/**
* After the class is created method.
*/
@AfterClass
- public static void tearDown() {
+ public static void tearDownAfterClass() {
HttpServletServer.factory.destroy();
HttpClient.factory.destroy();
assertEquals("PUT:hello:{myParameter=myValue}", body);
}
+ @Test
+ public void testHttpPutAuthClient_JacksonProvider() throws Exception {
+ final HttpClient client = HttpClient.factory.build(BusTopicParams.builder().clientName("testHttpAuthClient")
+ .useHttps(true).allowSelfSignedCerts(true).hostname("localhost").port(6667)
+ .basePath("junit/echo").userName("x").password("y").managed(true)
+ .serializationProvider(MyJacksonProvider.class.getCanonicalName()).build());
+
+ Entity<MyEntity> entity = Entity.entity(new MyEntity("myValue"), MediaType.APPLICATION_JSON);
+ final Response response = client.put("hello", entity, Collections.emptyMap());
+ final String body = HttpClient.getBody(response, String.class);
+
+ assertEquals(200, response.getStatus());
+ assertEquals("PUT:hello:{myParameter=myValue}", body);
+
+ assertTrue(MyJacksonProvider.hasWrittenSome());
+
+ assertFalse(MyGsonProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testHttpPutAuthClient_GsonProvider() throws Exception {
+ final HttpClient client = HttpClient.factory.build(BusTopicParams.builder().clientName("testHttpAuthClient")
+ .useHttps(true).allowSelfSignedCerts(true).hostname("localhost").port(6667)
+ .basePath("junit/echo").userName("x").password("y").managed(true)
+ .serializationProvider(MyGsonProvider.class.getCanonicalName()).build());
+
+ Entity<MyEntity> entity = Entity.entity(new MyEntity("myValue"), MediaType.APPLICATION_JSON);
+ final Response response = client.put("hello", entity, Collections.emptyMap());
+ final String body = HttpClient.getBody(response, String.class);
+
+ assertEquals(200, response.getStatus());
+ assertEquals("PUT:hello:{myParameter=myValue}", body);
+
+ assertTrue(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyJacksonProvider.hasWrittenSome());
+ }
+
@Test
public void testHttpAuthClient401() throws Exception {
final HttpClient client = getNoAuthHttpClient("testHttpAuthClient401", true,
final HttpClient clientPdp = HttpClient.factory.get("PDP");
final Response response2 = clientPdp.get("test");
assertEquals(500, response2.getStatus());
+
+ assertFalse(MyJacksonProvider.hasWrittenSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testHttpAuthClientProps_MixedProviders() throws Exception {
+ final Properties httpProperties = new Properties();
+
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES, "GSON,JACKSON");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, "localhost");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, "6666");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_URL_SUFFIX, "junit/echo");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, "false");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true");
+ httpProperties.setProperty(
+ PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "GSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
+ MyGsonProvider.class.getCanonicalName());
+
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, "localhost");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, "6666");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_URL_SUFFIX, "junit/echo");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, "false");
+ httpProperties.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true");
+ httpProperties.setProperty(
+ PolicyEndPointProperties.PROPERTY_HTTP_CLIENT_SERVICES + "." + "JACKSON"
+ + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
+ MyJacksonProvider.class.getCanonicalName());
+
+ final List<HttpClient> clients = HttpClient.factory.build(httpProperties);
+ assertEquals(2, clients.size());
+
+ Entity<MyEntity> entity = Entity.entity(new MyEntity("myValue"), MediaType.APPLICATION_JSON);
+
+ // use gson client
+ MyGsonProvider.resetSome();
+ MyJacksonProvider.resetSome();
+ HttpClient client = HttpClient.factory.get("GSON");
+
+ Response response = client.put("hello", entity, Collections.emptyMap());
+ String body = HttpClient.getBody(response, String.class);
+
+ assertEquals(200, response.getStatus());
+ assertEquals("PUT:hello:{myParameter=myValue}", body);
+
+ assertTrue(MyGsonProvider.hasWrittenSome());
+ assertFalse(MyJacksonProvider.hasWrittenSome());
+
+ // use jackson client
+ MyGsonProvider.resetSome();
+ MyJacksonProvider.resetSome();
+ client = HttpClient.factory.get("JACKSON");
+
+ response = client.put("hello", entity, Collections.emptyMap());
+ body = HttpClient.getBody(response, String.class);
+
+ assertEquals(200, response.getStatus());
+ assertEquals("PUT:hello:{myParameter=myValue}", body);
+
+ assertTrue(MyJacksonProvider.hasWrittenSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
}
- private HttpClient getAuthHttpClient() throws KeyManagementException, NoSuchAlgorithmException {
+ private HttpClient getAuthHttpClient()
+ throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
return HttpClient.factory.build(BusTopicParams.builder().clientName("testHttpAuthClient")
.useHttps(true).allowSelfSignedCerts(true).hostname("localhost").port(6667).basePath("junit/echo")
.userName("x").password("y").managed(true).build());
}
private HttpClient getNoAuthHttpClient(String clientName, boolean https, int port)
- throws KeyManagementException, NoSuchAlgorithmException {
+ throws KeyManagementException, NoSuchAlgorithmException, ClassNotFoundException {
return HttpClient.factory.build(BusTopicParams.builder().clientName(clientName)
.useHttps(https).allowSelfSignedCerts(https).hostname("localhost").port(port).basePath("junit/echo")
.userName(null).password(null).managed(true).build());
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-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.
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.net.ConnectException;
+import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
import java.util.UUID;
-
+import org.apache.commons.io.IOUtils;
+import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.Test;
import org.onap.policy.common.endpoints.http.server.HttpServletServer;
import org.slf4j.Logger;
*/
private static Logger logger = LoggerFactory.getLogger(HttpServerTest.class);
+ private static final String LOCALHOST_PREFIX = "http://localhost:";
+
+ private static final Gson gson = new Gson();
+
+ /**
+ * Server port. Incremented by 10 with each test.
+ */
+ private static int port = 5608;
+
+ private String portUrl;
+
+ /**
+ * Increments the port number, clears the servers, and resets the providers.
+ */
+ @Before
+ public void setUp() {
+ port += 10;
+ portUrl = LOCALHOST_PREFIX + port;
+
+ HttpServletServer.factory.destroy();
+
+ MyJacksonProvider.resetSome();
+ MyGsonProvider.resetSome();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() {
+ HttpServletServer.factory.destroy();
+ }
+
+ @Test
+ public void testDefaultPackageServer() throws Exception {
+ logger.info("-- testDefaultPackageServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+ server.addServletPackage("/*", this.getClass().getPackage().getName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+ }
+
+ @Test
+ public void testJacksonPackageServer() throws Exception {
+ logger.info("-- testJacksonPackageServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+
+ server.setSerializationProvider(MyJacksonProvider.class.getCanonicalName());
+ server.addServletPackage("/*", this.getClass().getPackage().getName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+
+ assertTrue(MyJacksonProvider.hasReadSome());
+ assertTrue(MyJacksonProvider.hasWrittenSome());
+
+ assertFalse(MyGsonProvider.hasReadSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testGsonPackageServer() throws Exception {
+ logger.info("-- testGsonPackageServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+
+ server.setSerializationProvider(MyGsonProvider.class.getCanonicalName());
+ server.addServletPackage("/*", this.getClass().getPackage().getName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+
+ assertTrue(MyGsonProvider.hasReadSome());
+ assertTrue(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyJacksonProvider.hasReadSome());
+ assertFalse(MyJacksonProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testDefaultClassServer() throws Exception {
+ logger.info("-- testDefaultClassServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+ server.addServletClass("/*", RestEchoService.class.getCanonicalName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+ }
+
+ @Test
+ public void testJacksonClassServer() throws Exception {
+ logger.info("-- testJacksonClassServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+ server.setSerializationProvider(MyJacksonProvider.class.getCanonicalName());
+ server.addServletClass("/*", RestEchoService.class.getCanonicalName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+
+ assertTrue(MyJacksonProvider.hasReadSome());
+ assertTrue(MyJacksonProvider.hasWrittenSome());
+
+ assertFalse(MyGsonProvider.hasReadSome());
+ assertFalse(MyGsonProvider.hasWrittenSome());
+ }
+
+ @Test
+ public void testGsonClassServer() throws Exception {
+ logger.info("-- testGsonClassServer() --");
+
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
+ server.setSerializationProvider(MyGsonProvider.class.getCanonicalName());
+ server.addServletClass("/*", RestEchoService.class.getCanonicalName());
+ server.addFilterClass("/*", TestFilter.class.getCanonicalName());
+ server.waitedStart(5000);
+
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+
+ RestEchoReqResp request = new RestEchoReqResp();
+ request.setRequestId(100);
+ request.setText("some text");
+ String reqText = gson.toJson(request);
+
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/full/request", reqText);
+ assertEquals(reqText, response);
+
+ assertTrue(MyGsonProvider.hasReadSome());
+ assertTrue(MyGsonProvider.hasWrittenSome());
+
+ assertFalse(MyJacksonProvider.hasReadSome());
+ assertFalse(MyJacksonProvider.hasWrittenSome());
+ }
+
@Test
public void testSingleServer() throws Exception {
logger.info("-- testSingleServer() --");
- HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", 5678, "/", false, true);
+ HttpServletServer server = HttpServletServer.factory.build("echo", "localhost", port, "/", false, true);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.addFilterClass("/*", TestFilter.class.getCanonicalName());
server.waitedStart(5000);
- assertTrue(HttpServletServer.factory.get(5678).isAlive());
- assertFalse(HttpServletServer.factory.get(5678).isAaf());
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+ assertFalse(HttpServletServer.factory.get(port).isAaf());
- String response = http(HttpServletServer.factory.get(5678), "http://localhost:5678/junit/echo/hello");
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello");
assertTrue("hello".equals(response));
response = null;
try {
- response = http(HttpServletServer.factory.get(5678), "http://localhost:5678/swagger.json");
+ response = http(HttpServletServer.factory.get(port), portUrl + "/swagger.json");
} catch (IOException e) {
// Expected
}
assertTrue(response == null);
- response = http(HttpServletServer.factory.get(5678), "http://localhost:5678/junit/echo/hello?block=true");
+ response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello?block=true");
assertEquals("FILTERED", response);
- assertTrue(HttpServletServer.factory.get(5678).isAlive());
- assertTrue(HttpServletServer.factory.inventory().size() == 1);
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+ assertEquals(1, HttpServletServer.factory.inventory().size());
server.setAafAuthentication("/*");
- assertTrue(HttpServletServer.factory.get(5678).isAaf());
+ assertTrue(HttpServletServer.factory.get(port).isAaf());
- HttpServletServer.factory.destroy(5678);
- assertTrue(HttpServletServer.factory.inventory().size() == 0);
+ HttpServletServer.factory.destroy(port);
+ assertEquals(0, HttpServletServer.factory.inventory().size());
}
@Test
public void testMultipleServers() throws Exception {
logger.info("-- testMultipleServers() --");
- HttpServletServer server1 = HttpServletServer.factory.build("echo-1", false,"localhost", 5688, "/", true, true);
+ HttpServletServer server1 = HttpServletServer.factory.build("echo-1", false,"localhost", port, "/", true, true);
server1.addServletPackage("/*", this.getClass().getPackage().getName());
server1.waitedStart(5000);
- HttpServletServer server2 = HttpServletServer.factory.build("echo-2", "localhost", 5689, "/", false, true);
+ int port2 = port + 1;
+
+ HttpServletServer server2 = HttpServletServer.factory.build("echo-2", "localhost", port2, "/", false, true);
server2.addServletPackage("/*", this.getClass().getPackage().getName());
server2.waitedStart(5000);
- assertTrue(HttpServletServer.factory.get(5688).isAlive());
- assertTrue(HttpServletServer.factory.get(5689).isAlive());
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
+ assertTrue(HttpServletServer.factory.get(port2).isAlive());
- String response = http(HttpServletServer.factory.get(5688), "http://localhost:5688/junit/echo/hello");
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello");
assertTrue("hello".equals(response));
- response = http(HttpServletServer.factory.get(5688), "http://localhost:5688/swagger.json");
+ response = http(HttpServletServer.factory.get(port), portUrl + "/swagger.json");
assertTrue(response != null);
- response = http(HttpServletServer.factory.get(5689), "http://localhost:5689/junit/echo/hello");
+ response = http(HttpServletServer.factory.get(port2), LOCALHOST_PREFIX + port2 + "/junit/echo/hello");
assertTrue("hello".equals(response));
response = null;
try {
- response = http(HttpServletServer.factory.get(5689), "http://localhost:5689/swagger.json");
+ response = http(HttpServletServer.factory.get(port2), LOCALHOST_PREFIX + port2 + "/swagger.json");
} catch (IOException e) {
// Expected
}
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5668, "/", false, true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", port, "/", false, true);
server.addServletPackage("/*", this.getClass().getPackage().getName());
server.waitedStart(5000);
- assertTrue(HttpServletServer.factory.get(5668).isAlive());
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
- String response = http(HttpServletServer.factory.get(5668), "http://localhost:5668/junit/echo/hello");
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello");
assertTrue("hello".equals(response));
- response = http(HttpServletServer.factory.get(5668), "http://localhost:5668/junit/endpoints/http/servers");
+ response = http(HttpServletServer.factory.get(port), portUrl + "/junit/endpoints/http/servers");
assertTrue(response.contains(randomName));
HttpServletServer.factory.destroy();
logger.info("-- testServiceClass() --");
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5658, "/", false, true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", port, "/", false, true);
server.addServletClass("/*", RestEchoService.class.getCanonicalName());
server.waitedStart(5000);
- assertTrue(HttpServletServer.factory.get(5658).isAlive());
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
- String response = http(HttpServletServer.factory.get(5658), "http://localhost:5658/junit/echo/hello");
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello");
assertTrue("hello".equals(response));
HttpServletServer.factory.destroy();
String randomName = UUID.randomUUID().toString();
- HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", 5648, "/", false, true);
+ HttpServletServer server = HttpServletServer.factory.build(randomName, "localhost", port, "/", false, true);
server.addServletClass("/*", RestEchoService.class.getCanonicalName());
server.addServletClass("/*", RestEndpoints.class.getCanonicalName());
server.waitedStart(5000);
- assertTrue(HttpServletServer.factory.get(5648).isAlive());
+ assertTrue(HttpServletServer.factory.get(port).isAlive());
- String response = http(HttpServletServer.factory.get(5648), "http://localhost:5648/junit/echo/hello");
+ String response = http(HttpServletServer.factory.get(port), portUrl + "/junit/echo/hello");
assertTrue("hello".equals(response));
- response = http(HttpServletServer.factory.get(5648), "http://localhost:5648/junit/endpoints/http/servers");
+ response = http(HttpServletServer.factory.get(port), portUrl + "/junit/endpoints/http/servers");
assertTrue(response.contains(randomName));
HttpServletServer.factory.destroy();
/**
* performs an http request.
- *
+ *
* @throws MalformedURLException make sure URL is good
* @throws IOException thrown is IO exception occurs
* @throws InterruptedException thrown if thread interrupted occurs
int maxNumberRetries = 5;
while (numRetries <= maxNumberRetries) {
try {
- response = response(url);
+ URLConnection conn = url.openConnection();
+ response = response(conn);
break;
} catch (ConnectException e) {
logger.warn("http server {} @ {} ({}) - cannot connect yet ..", server, urlString, numRetries, e);
return response;
}
+ /**
+ * Performs an http request.
+ *
+ * @throws MalformedURLException make sure URL is good
+ * @throws IOException thrown is IO exception occurs
+ * @throws InterruptedException thrown if thread interrupted occurs
+ */
+ protected String http(HttpServletServer server, String urlString, String post)
+ throws MalformedURLException, IOException, InterruptedException {
+ URL url = new URL(urlString);
+ String response = null;
+ int numRetries = 1;
+ int maxNumberRetries = 5;
+ while (numRetries <= maxNumberRetries) {
+ try {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Content-Type", "application/json");
+ IOUtils.write(post, conn.getOutputStream());
+ response = response(conn);
+ break;
+ } catch (ConnectException e) {
+ logger.warn("http server {} @ {} ({}) - cannot connect yet ..", server, urlString, numRetries, e);
+ numRetries++;
+ Thread.sleep(10000L);
+ } catch (Exception e) {
+ logger.error("http error", e);
+ throw e;
+ }
+ }
+
+ return response;
+ }
+
/**
* gets http response.
- *
- * @param url url
- *
+ *
+ * @param conn connection from which to read
+ *
* @throws IOException if an I/O error occurs
*/
- protected String response(URL url) throws IOException {
+ protected String response(URLConnection conn) throws IOException {
String response = "";
- try (BufferedReader ioReader = new BufferedReader(new InputStreamReader(url.openStream()))) {
+ try (BufferedReader ioReader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String line;
while ((line = ioReader.readLine()) != null) {
response += line;
return response;
}
-
-
}
--- /dev/null
+/*
+ * ============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 org.onap.policy.common.endpoints.http.server.internal.GsonMessageBodyHandler;
+
+/**
+ * GsonMessageBodyHandler that tracks activities.
+ */
+public class MyGsonProvider extends GsonMessageBodyHandler {
+ private static boolean readSome = false;
+ private static boolean wroteSome = false;
+
+ /**
+ * Constructs the object and resets the variables to indicate that no activity has
+ * occurred yet.
+ */
+ public MyGsonProvider() {
+ super();
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
+
+ readSome = 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 {
+
+ wroteSome = 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() {
+ MyGsonProvider.readSome = false;
+ MyGsonProvider.wroteSome = false;
+ }
+
+}
--- /dev/null
+/*
+ * ============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 com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+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;
+
+/**
+ * JacksonJsonProvider that tracks activities.
+ */
+public class MyJacksonProvider extends JacksonJsonProvider {
+ private static boolean readSome = false;
+ private static boolean wroteSome = false;
+
+ /**
+ * Constructs the object and resets the variables to indicate that no activity has
+ * occurred yet.
+ */
+ public MyJacksonProvider() {
+ super();
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
+
+ readSome = 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 {
+
+ wroteSome = 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() {
+ MyJacksonProvider.readSome = false;
+ MyJacksonProvider.wroteSome = false;
+ }
+
+}
--- /dev/null
+/*
+ * ============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 com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * "ECHO" request and response supporting serialization and de-serialization via
+ * both jackson and gson.
+ */
+public class RestEchoReqResp {
+ @JsonProperty("reqId")
+ @SerializedName("reqId")
+ private int requestId;
+
+ @JsonProperty("textValue")
+ @SerializedName("textValue")
+ private String text;
+
+ public int getRequestId() {
+ return requestId;
+ }
+
+ public void setRequestId(int requestId) {
+ this.requestId = requestId;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return "RestEchoReqResp [requestId=" + requestId + ", text=" + text + "]";
+ }
+}
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
-
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
@Api(value = "echo")
return "PUT:" + word + ":" + entity.toString();
}
+ @POST
+ @Path("/full/request")
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "echoes back the request structure", response = RestEchoReqResp.class)
+ public Response echoFullyPost(RestEchoReqResp reqResp) {
+ return Response.status(Status.OK).entity(reqResp).build();
+ }
+
@POST
@Path("{word}")
@Produces(MediaType.TEXT_PLAIN)