2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.common.endpoints.http.server.internal;
23 import io.swagger.jersey.config.JerseyJaxrsConfig;
24 import java.util.HashMap;
25 import org.eclipse.jetty.servlet.ServletHolder;
26 import org.onap.policy.common.utils.network.NetworkUtil;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * REST Jetty Server that uses Jersey Servlets to support JAX-RS Web Services.
33 public class JettyJerseyServer extends JettyServletServer {
36 * Swagger API Base Path.
38 protected static final String SWAGGER_API_BASEPATH = "swagger.api.basepath";
43 protected static final String SWAGGER_CONTEXT_ID = "swagger.context.id";
48 protected static final String SWAGGER_SCANNER_ID = "swagger.scanner.id";
51 * Swagger Pretty Print.
53 protected static final String SWAGGER_PRETTY_PRINT = "swagger.pretty.print";
58 protected static final String SWAGGER_INIT_PACKAGES_PARAM_VALUE = "io.swagger.jaxrs.listing";
61 * Jersey Packages Init Param Name.
63 protected static final String JERSEY_INIT_PACKAGES_PARAM_NAME = "jersey.config.server.provider.packages";
66 * Jersey Packages Init Param Value.
68 protected static final String JERSEY_INIT_PACKAGES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json";
71 * Jersey Classes Init Param Name.
73 protected static final String JERSEY_INIT_CLASSNAMES_PARAM_NAME = "jersey.config.server.provider.classnames";
76 * Jersey Jackson Classes Init Param Value.
78 protected static final String JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE =
79 "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider";
82 * Jersey Swagger Classes Init Param Value.
84 protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE =
85 "io.swagger.jaxrs.listing.ApiListingResource," + "io.swagger.jaxrs.listing.SwaggerSerializers";
89 protected static Logger logger = LoggerFactory.getLogger(JettyJerseyServer.class);
92 * Container for servlets.
94 protected HashMap<String, ServletHolder> servlets = new HashMap<>();
99 protected String swaggerId = null;
105 * @param https enable https?
106 * @param host host server host
107 * @param port port server port
108 * @param swagger support swagger?
109 * @param contextPath context path
111 * @throws IllegalArgumentException in invalid arguments are provided
113 public JettyJerseyServer(String name, boolean https, String host, int port, String contextPath, boolean swagger) {
115 super(name, https, host, port, contextPath);
117 this.swaggerId = "swagger-" + this.port;
118 attachSwaggerServlet(https);
123 * Attaches a swagger initialization servlet.
125 protected void attachSwaggerServlet(boolean https) {
127 ServletHolder swaggerServlet = context.addServlet(JerseyJaxrsConfig.class, "/");
129 String hostname = this.connector.getHost();
130 if (hostname == null || hostname.isEmpty() || hostname.equals(NetworkUtil.IPv4_WILDCARD_ADDRESS)) {
131 hostname = NetworkUtil.getHostname();
134 swaggerServlet.setInitParameter(SWAGGER_API_BASEPATH,
135 ((https) ? "https://" : "http://") + hostname + ":" + this.connector.getPort() + "/");
136 swaggerServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
137 swaggerServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
138 swaggerServlet.setInitParameter(SWAGGER_PRETTY_PRINT, "true");
139 swaggerServlet.setInitOrder(2);
141 if (logger.isDebugEnabled()) {
142 logger.debug("{}: Swagger Servlet has been attached: {}", this, swaggerServlet.dump());
147 * Retrieves cached server based on servlet path.
149 * @param servletPath servlet path
150 * @return the jetty servlet holder
152 * @throws IllegalArgumentException if invalid arguments are provided
154 protected synchronized ServletHolder getServlet(String servletPath) {
156 ServletHolder jerseyServlet = servlets.get(servletPath);
157 if (jerseyServlet == null) {
158 jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
159 jerseyServlet.setInitOrder(0);
160 servlets.put(servletPath, jerseyServlet);
163 return jerseyServlet;
167 public synchronized void addServletPackage(String servletPath, String restPackage) {
168 String servPath = servletPath;
169 if (restPackage == null || restPackage.isEmpty()) {
170 throw new IllegalArgumentException("No discoverable REST package provided");
173 if (servPath == null || servPath.isEmpty()) {
177 ServletHolder jerseyServlet = this.getServlet(servPath);
179 String initClasses = jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
180 if (initClasses != null && !initClasses.isEmpty()) {
181 logger.warn("Both packages and classes are used in Jetty+Jersey Configuration: {}", restPackage);
184 String initPackages = jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
185 if (initPackages == null) {
186 if (this.swaggerId != null) {
188 JERSEY_INIT_PACKAGES_PARAM_VALUE + "," + SWAGGER_INIT_PACKAGES_PARAM_VALUE + "," + restPackage;
190 jerseyServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
191 jerseyServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
193 initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," + restPackage;
196 initPackages = initPackages + "," + restPackage;
199 jerseyServlet.setInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME, initPackages);
201 if (logger.isDebugEnabled()) {
202 logger.debug("{}: added REST package: {}", this, jerseyServlet.dump());
207 public synchronized void addServletClass(String servletPath, String restClass) {
209 if (restClass == null || restClass.isEmpty()) {
210 throw new IllegalArgumentException("No discoverable REST class provided");
213 if (servletPath == null || servletPath.isEmpty()) {
217 ServletHolder jerseyServlet = this.getServlet(servletPath);
219 String initPackages = jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
220 if (initPackages != null && !initPackages.isEmpty()) {
221 logger.warn("Both classes and packages are used in Jetty+Jersey Configuration: {}", restClass);
224 String initClasses = jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
225 if (initClasses == null) {
226 if (this.swaggerId != null) {
227 initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + SWAGGER_INIT_CLASSNAMES_PARAM_VALUE
230 jerseyServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
231 jerseyServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
233 initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + restClass;
236 initClasses = initClasses + "," + restClass;
239 jerseyServlet.setInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME, initClasses);
241 if (logger.isDebugEnabled()) {
242 logger.debug("{}: added REST class: {}", this, jerseyServlet.dump());
247 public String toString() {
248 StringBuilder builder = new StringBuilder();
249 builder.append("JettyJerseyServer [servlets=").append(servlets).append(", swaggerId=").append(swaggerId)
250 .append(", toString()=").append(super.toString()).append("]");
251 return builder.toString();