============LICENSE_START=======================================================
Copyright (C) 2018 Ericsson. All rights reserved.
Modifications Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved.
- Modifications Copyright (C) 2019 Nordix Foundation.
+ Modifications Copyright (C) 2019-2020 Nordix Foundation.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
<cambria.version>1.2.1-oss</cambria.version>
<http.client.version>4.5.5</http.client.version>
<http.core.version>4.4.4</http.core.version>
+ <!--This is required since oparent does not include jetty-servlets. TBD get oparent updated -->
+ <jetty.version>9.4.24.v20191120</jetty.version>
</properties>
<dependencies>
<artifactId>jetty-servlet</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
void addServletPackage(String servletPath, String restPackage);
/**
- * Add org.eclipse.jetty.servlet.DefaultServlet into context
+ * Add a static resource path to manage static resources.
*
* @param servletPath servlet path
* @param resourceBase static resources folder
* policy-endpoints
* ================================================================================
* Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* 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.
public interface HttpServletServerFactory {
/**
- * Builds an http or https server with support for servlets.
- *
+ * Builds an http or https rest server with support for servlets.
+ *
* @param name name
* @param https use secured http over tls connection
* @param host binding host
boolean managed);
/**
- * Builds an http server with support for servlets.
+ * Builds an http rest server with support for servlets.
*
* @param name name
* @param host binding host
HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger, boolean managed);
/**
- * Build a list of http servers per properties.
- *
+ * Build a list of http rest servers per properties.
+ *
* @param properties properties based configuration
* @return list of http servers
* @throws IllegalArgumentException when invalid parameters are provided
*/
List<HttpServletServer> build(Properties properties);
+ /**
+ * Builds an http or https server to manage static resources.
+ *
+ * @param name name
+ * @param https use secured http over tls connection
+ * @param host binding host
+ * @param port port
+ * @param contextPath server base path
+ * @param managed is it managed by infrastructure
+ * @return http server
+ * @throws IllegalArgumentException when invalid parameters are provided
+ */
+ HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port, String contextPath,
+ boolean managed);
+
/**
* Gets a server based on the port.
- *
+ *
* @param port port
* @return http server
*/
/**
* Provides an inventory of servers.
- *
+ *
* @return inventory of servers
*/
List<HttpServletServer> inventory();
/**
* Destroys server bound to a port.
- *
+ *
* @param port the port the server is bound to
*/
void destroy(int port);
* ONAP Policy Engine - Common Modules
* ================================================================================
* Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer;
+import org.onap.policy.common.endpoints.http.server.internal.JettyStaticResourceServer;
import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
import org.onap.policy.common.endpoints.utils.PropertyUtils;
import org.slf4j.Logger;
return serviceList;
}
+
+
+ @Override
+ public HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port,
+ String contextPath, boolean managed) {
+ if (servers.containsKey(port)) {
+ return servers.get(port);
+ }
+
+ JettyStaticResourceServer server = new JettyStaticResourceServer(name, https, host, port, contextPath);
+ if (managed) {
+ servers.put(port, server);
+ }
+
+ return server;
+ }
+
private void addService(ArrayList<HttpServletServer> serviceList, String serviceName, Properties properties) {
String servicePrefix = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + serviceName;
import io.swagger.jersey.config.JerseyJaxrsConfig;
import java.util.HashMap;
+import java.util.Map;
import org.apache.commons.lang3.StringUtils;
-import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ServerProperties;
import org.onap.policy.common.utils.network.NetworkUtil;
protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE =
"io.swagger.jaxrs.listing.ApiListingResource," + "io.swagger.jaxrs.listing.SwaggerSerializers";
- /**
- * Servlet Holder Resource Base Path.
- */
- protected static final String SERVLET_HOLDER_RESOURCE_BASE = "resourceBase";
-
- /**
- * Servlet Holder Directory Allowed.
- */
- protected static final String SERVLET_HOLDER_DIR_ALLOWED = "dirAllowed";
-
- /**
- * Servlet Holder Path Information Only.
- */
- protected static final String SERVLET_HOLDER_PATH_INFO_ONLY = "pathInfoOnly";
-
/**
* Logger.
*/
protected static Logger logger = LoggerFactory.getLogger(JettyJerseyServer.class);
/**
- * Container for jersey servlets.
+ * Container for servlets.
*/
- protected HashMap<String, ServletHolder> jerseyServlets = new HashMap<>();
-
- /**
- * Container for default servlets.
- */
- protected HashMap<String, ServletHolder> defaultServlets = new HashMap<>();
+ protected final Map<String, ServletHolder> servlets = new HashMap<>();
/**
* Swagger ID.
*
* @throws IllegalArgumentException if invalid arguments are provided
*/
- protected synchronized ServletHolder getJerseyServlet(String servletPath) {
+ protected synchronized ServletHolder getServlet(String servletPath) {
- return jerseyServlets.computeIfAbsent(servletPath, key -> {
+ return servlets.computeIfAbsent(servletPath, key -> {
ServletHolder jerseyServlet =
context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
});
}
- /**
- * Retrieves cached default servlet based on servlet path.
- *
- * @param servletPath servlet path
- * @return the jetty servlet holder
- *
- * @throws IllegalArgumentException if invalid arguments are provided
- */
- protected synchronized ServletHolder getDefaultServlet(String servPath) {
-
- return defaultServlets.computeIfAbsent(servPath, key -> context.addServlet(DefaultServlet.class, servPath));
- }
-
@Override
public synchronized void addServletPackage(String servletPath, String restPackage) {
String servPath = servletPath;
servPath = "/*";
}
- ServletHolder jerseyServlet = this.getJerseyServlet(servPath);
+ ServletHolder jerseyServlet = this.getServlet(servPath);
initStandardParams(jerseyServlet);
servletPath = "/*";
}
- ServletHolder jerseyServlet = this.getJerseyServlet(servletPath);
+ ServletHolder jerseyServlet = this.getServlet(servletPath);
initStandardParams(jerseyServlet);
}
}
- @Override
- public synchronized void addServletResource(String servletPath, String resoureBase) {
-
- if (StringUtils.isBlank(resoureBase)) {
- throw new IllegalArgumentException("No resourceBase provided");
- }
-
- if (servletPath == null || servletPath.isEmpty()) {
- servletPath = "/*";
- }
-
- ServletHolder defaultServlet = this.getDefaultServlet(servletPath);
-
- defaultServlet.setInitParameter(SERVLET_HOLDER_RESOURCE_BASE, resoureBase);
- defaultServlet.setInitParameter(SERVLET_HOLDER_DIR_ALLOWED, "false");
- defaultServlet.setInitParameter(SERVLET_HOLDER_PATH_INFO_ONLY, "true");
-
- if (logger.isDebugEnabled()) {
- logger.debug("{}: added REST class: {}", this, defaultServlet.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
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("JettyJerseyServer [Jerseyservlets=").append(jerseyServlets).append(", Defaultservlets=")
- .append(defaultServlets).append(", swaggerId=").append(swaggerId).append(", toString()=")
- .append(super.toString()).append("]");
+ builder.append("JettyJerseyServer [Jerseyservlets=").append(servlets).append(", swaggerId=").append(swaggerId)
+ .append(", toString()=").append(super.toString()).append("]");
return builder.toString();
}
}
* ONAP
* ================================================================================
* Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
private static Logger logger = LoggerFactory.getLogger(JettyServletServer.class);
+ private static final String NOT_SUPPORTED = " is not supported on this type of jetty server";
+
/**
* Server name.
*/
return password;
}
+ @Override
+ public void setSerializationProvider(String provider) {
+ throw new UnsupportedOperationException("setSerializationProvider()" + NOT_SUPPORTED);
+ }
+
+ @Override
+ public void addServletClass(String servletPath, String restClass) {
+ throw new UnsupportedOperationException("addServletClass()" + NOT_SUPPORTED);
+ }
+
+ @Override
+ public void addServletPackage(String servletPath, String restPackage) {
+ throw new UnsupportedOperationException("addServletPackage()" + NOT_SUPPORTED);
+ }
+
+ @Override
+ public void addServletResource(String servletPath, String resourceBase) {
+ throw new UnsupportedOperationException("addServletResource()" + NOT_SUPPORTED);
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.endpoints.http.server.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import lombok.ToString;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Jetty Server that uses DefaultServlets to support web static resources management.
+ */
+@ToString
+public class JettyStaticResourceServer extends JettyServletServer {
+
+ /**
+ * Servlet Holder Resource Base Path.
+ */
+ protected static final String SERVLET_HOLDER_RESOURCE_BASE = "resourceBase";
+
+ /**
+ * Servlet Holder Directory Allowed.
+ */
+ protected static final String SERVLET_HOLDER_DIR_ALLOWED = "dirAllowed";
+
+ /**
+ * Servlet Holder Path Information Only.
+ */
+ protected static final String SERVLET_HOLDER_PATH_INFO_ONLY = "pathInfoOnly";
+
+ /**
+ * Logger.
+ */
+ protected static Logger logger = LoggerFactory.getLogger(JettyStaticResourceServer.class);
+
+ /**
+ * Container for default servlets.
+ */
+ protected final Map<String, ServletHolder> servlets = new HashMap<>();
+
+ /**
+ * Constructor.
+ *
+ * @param name name
+ * @param https enable https?
+ * @param host host server host
+ * @param port port server port
+ * @param contextPath context path
+ *
+ * @throws IllegalArgumentException in invalid arguments are provided
+ */
+ public JettyStaticResourceServer(String name, boolean https, String host, int port, String contextPath) {
+
+ super(name, https, host, port, contextPath);
+ }
+
+ /**
+ * Retrieves cached default servlet based on servlet path.
+ *
+ * @param servletPath servlet path
+ * @return the jetty servlet holder
+ *
+ * @throws IllegalArgumentException if invalid arguments are provided
+ */
+ protected synchronized ServletHolder getDefaultServlet(String servPath) {
+
+ return servlets.computeIfAbsent(servPath, key -> context.addServlet(DefaultServlet.class, servPath));
+ }
+
+ @Override
+ public synchronized void addServletResource(String servletPath, String resoureBase) {
+
+ if (StringUtils.isBlank(resoureBase)) {
+ throw new IllegalArgumentException("No resourceBase provided");
+ }
+
+ if (servletPath == null || servletPath.isEmpty()) {
+ servletPath = "/*";
+ }
+
+ ServletHolder defaultServlet = this.getDefaultServlet(servletPath);
+
+ defaultServlet.setInitParameter(SERVLET_HOLDER_RESOURCE_BASE, resoureBase);
+ defaultServlet.setInitParameter(SERVLET_HOLDER_DIR_ALLOWED, "false");
+ defaultServlet.setInitParameter(SERVLET_HOLDER_PATH_INFO_ONLY, "true");
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("{}: added Default Servlet: {}", this, defaultServlet.dump());
+ }
+ }
+}
* ONAP
* ================================================================================
* Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.policy.common.endpoints.http.server.test;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.catchThrowable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.google.gson.Gson;
+
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
assertTrue(HttpServletServerFactoryInstance.getServerFactory().inventory().isEmpty());
}
+ @Test
+ public void testSingleStaticResourceServer() throws Exception {
+ logger.info("-- testSingleStaticResourceServer() --");
+
+ HttpServletServer staticServer = HttpServletServerFactoryInstance.getServerFactory()
+ .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+ Throwable thrown = catchThrowable(() -> staticServer.addServletResource("/*", null));
+ assertThat(thrown).isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No resourceBase provided");
+
+ staticServer.addServletResource(null,
+ HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
+
+ thrown = catchThrowable(() -> staticServer.addServletClass("/*", RestEchoService.class.getName()));
+ assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("is not supported on this type of jetty server");
+
+ thrown = catchThrowable(() -> staticServer.addServletPackage("/api/*", this.getClass().getPackage().getName()));
+ assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("is not supported on this type of jetty server");
+
+ thrown = catchThrowable(() -> staticServer.setSerializationProvider(MyGsonProvider.class.getName()));
+ assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("is not supported on this type of jetty server");
+
+ staticServer.waitedStart(5000);
+
+ assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
+ assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+
+ String response = http(portUrl);
+ assertThat(response).contains("Test Jetty Static Resources Root");
+
+ HttpServletServerFactoryInstance.getServerFactory().destroy(port);
+ assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+ }
+
+ @Test
+ public void testMultiStaticResourceServer() throws Exception {
+ logger.info("-- testMultiStaticResourceServer() --");
+
+ HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
+ .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+ staticResourceServer.addServletResource("/root/*",
+ HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
+ staticResourceServer.addServletResource("/alt-root/*",
+ HttpServerTest.class.getClassLoader().getResource("webapps/alt-root").toExternalForm());
+ staticResourceServer.waitedStart(5000);
+
+ assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
+ assertEquals(1, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+
+ String response = http(portUrl + "/root/");
+ assertThat(response).contains("Test Jetty Static Resources Root");
+
+ response = http(portUrl + "/alt-root/");
+ assertThat(response).contains("Test Jetty Static Resources Alt-Root");
+
+ HttpServletServerFactoryInstance.getServerFactory().destroy(port);
+ assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+ }
+
+ @Test
+ public void testMultiTypesServer() throws Exception {
+ logger.info("-- testMultiTypesServer() --");
+
+ HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
+ .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+ staticResourceServer.addServletResource("/root/*",
+ HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
+ staticResourceServer.waitedStart(5000);
+
+ int port2 = port + 1;
+ HttpServletServer jerseyServer =
+ HttpServletServerFactoryInstance.getServerFactory().build("echo", LOCALHOST, port2, "/", false, true);
+ jerseyServer.addServletPackage("/api/*", this.getClass().getPackage().getName());
+
+ Throwable thrown = catchThrowable(() -> jerseyServer.addServletResource("/root/*",
+ HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm()));
+ assertThat(thrown).isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("is not supported on this type of jetty server");
+
+ jerseyServer.waitedStart(5000);
+
+ assertTrue(HttpServletServerFactoryInstance.getServerFactory().get(port).isAlive());
+ assertEquals(2, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+
+ String response = http(portUrl + "/root/");
+ assertThat(response).contains("Test Jetty Static Resources Root");
+
+ response = http(LOCALHOST_PREFIX + port2 + "/api" + JUNIT_ECHO_HELLO);
+ assertEquals(HELLO, response);
+
+ HttpServletServerFactoryInstance.getServerFactory().destroy();
+ assertEquals(0, HttpServletServerFactoryInstance.getServerFactory().inventory().size());
+ }
+
/**
* performs an http request.
*
--- /dev/null
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2020 Nordix Foundation.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+-->
+
+<html>
+ <head>
+ <title>Hello World</title>
+ </head>
+ <body>
+ <h4>Test Jetty Static Resources Alt-Root</h4>
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2020 Nordix Foundation.
+ ================================================================================
+ 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.
+
+ SPDX-License-Identifier: Apache-2.0
+ ============LICENSE_END=========================================================
+-->
+
+<html>
+ <head>
+ <title>Hello World</title>
+ </head>
+ <body>
+ <h4>Test Jetty Static Resources Root</h4>
+ </body>
+</html>
\ No newline at end of file