2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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=========================================================
20 package org.onap.policy.drools.http.server.internal;
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
24 import java.util.HashMap;
26 import org.eclipse.jetty.servlet.ServletHolder;
27 import org.slf4j.LoggerFactory;
28 import org.slf4j.Logger;
30 import io.swagger.jersey.config.JerseyJaxrsConfig;
33 * REST Jetty Server that uses Jersey Servlets to support JAX-RS Web Services
35 public class JettyJerseyServer extends JettyServletServer {
38 * Jersey Packages Init Param Name
40 protected static final String JERSEY_INIT_PACKAGES_PARAM_NAME = "jersey.config.server.provider.packages";
43 * Jersey Packages Init Param Value
45 protected static final String JERSEY_INIT_PACKAGES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json";
50 protected static final String SWAGGER_INIT_PACKAGES_PARAM_VALUE = "io.swagger.jaxrs.listing";
53 * Jersey Classes Init Param Name
55 protected static final String JERSEY_INIT_CLASSNAMES_PARAM_NAME = "jersey.config.server.provider.classnames";
58 * Jersey Jackson Classes Init Param Value
60 protected static final String JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider";
63 * Jersey Swagger Classes Init Param Value
65 protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE = "io.swagger.jaxrs.listing.ApiListingResource," +
66 "io.swagger.jaxrs.listing.SwaggerSerializers";
70 protected static Logger logger = LoggerFactory.getLogger(JettyJerseyServer.class);
73 * Container for servlets
75 protected HashMap<String, ServletHolder> servlets = new HashMap<String, ServletHolder>();
80 protected String swaggerId = null;
86 * @param host host server host
87 * @param port port server port
88 * @param swagger support swagger?
89 * @param contextPath context path
91 * @throws IllegalArgumentException in invalid arguments are provided
93 public JettyJerseyServer(String name, String host, int port, String contextPath, boolean swagger)
94 throws IllegalArgumentException {
96 super(name, host, port, contextPath);
98 this.swaggerId = "swagger-" + this.port;
99 attachSwaggerServlet();
104 * attaches a swagger initialization servlet
106 protected void attachSwaggerServlet() {
108 ServletHolder swaggerServlet = context.addServlet(JerseyJaxrsConfig.class, "/");
110 String hostname = this.connector.getHost();
111 if (hostname == null || hostname.isEmpty() || hostname.equals("0.0.0.0")) {
113 hostname = InetAddress.getLocalHost().getHostName();
114 } catch (UnknownHostException e) {
115 logger.warn("{}: can't resolve connector's hostname: ", this);
116 hostname = "localhost";
120 swaggerServlet.setInitParameter("swagger.api.basepath",
121 "http://" + hostname + ":" + this.connector.getPort() + "/");
122 swaggerServlet.setInitParameter("swagger.context.id", swaggerId);
123 swaggerServlet.setInitParameter("swagger.scanner.id", swaggerId);
124 swaggerServlet.setInitParameter("swagger.pretty.print", "true");
125 swaggerServlet.setInitOrder(2);
127 if (logger.isDebugEnabled())
128 logger.debug("{}: Swagger Servlet has been attached: {}", this, swaggerServlet.dump());
132 * retrieves cached server based on servlet path
134 * @param servletPath servlet path
135 * @return the jetty servlet holder
137 * @throws IllegalArgumentException if invalid arguments are provided
139 protected synchronized ServletHolder getServlet(String servletPath)
140 throws IllegalArgumentException {
142 ServletHolder jerseyServlet = servlets.get(servletPath);
143 if (jerseyServlet == null) {
144 jerseyServlet = context.addServlet
145 (org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
146 jerseyServlet.setInitOrder(0);
147 servlets.put(servletPath, jerseyServlet);
150 return jerseyServlet;
154 public synchronized void addServletPackage(String servletPath, String restPackage)
155 throws IllegalArgumentException, IllegalStateException {
157 if (restPackage == null || restPackage.isEmpty())
158 throw new IllegalArgumentException("No discoverable REST package provided");
160 if (servletPath == null || servletPath.isEmpty())
163 ServletHolder jerseyServlet = this.getServlet(servletPath);
166 jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
167 if (initClasses != null && !initClasses.isEmpty())
168 logger.warn("Both packages and classes are used in Jetty+Jersey Configuration: {}", restPackage);
170 String initPackages =
171 jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
172 if (initPackages == null) {
173 if (this.swaggerId != null) {
174 initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," +
175 SWAGGER_INIT_PACKAGES_PARAM_VALUE + "," +
178 jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
179 jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
181 initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," +
185 initPackages = initPackages + "," + restPackage;
188 jerseyServlet.setInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME, initPackages);
190 if (logger.isDebugEnabled())
191 logger.debug("{}: added REST package: {}", this, jerseyServlet.dump());
195 public synchronized void addServletClass(String servletPath, String restClass)
196 throws IllegalArgumentException, IllegalStateException {
198 if (restClass == null || restClass.isEmpty())
199 throw new IllegalArgumentException("No discoverable REST class provided");
201 if (servletPath == null || servletPath.isEmpty())
204 ServletHolder jerseyServlet = this.getServlet(servletPath);
206 String initPackages =
207 jerseyServlet.getInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME);
208 if (initPackages != null && !initPackages.isEmpty())
209 logger.warn("Both classes and packages are used in Jetty+Jersey Configuration: {}", restClass);
212 jerseyServlet.getInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME);
213 if (initClasses == null) {
214 if (this.swaggerId != null) {
215 initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," +
216 SWAGGER_INIT_CLASSNAMES_PARAM_VALUE + "," +
219 jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
220 jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
222 initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + restClass;
225 initClasses = initClasses + "," + restClass;
228 jerseyServlet.setInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME, initClasses);
230 if (logger.isDebugEnabled())
231 logger.debug("{}: added REST class: {}", this, jerseyServlet.dump());
235 public String toString() {
236 StringBuilder builder = new StringBuilder();
237 builder.append("JettyJerseyServer [servlets=").append(servlets).append(", swaggerId=").append(swaggerId)
238 .append(", toString()=").append(super.toString()).append("]");
239 return builder.toString();