[POLICY-72] replace openecomp for drools-pdp
[policy/drools-pdp.git] / policy-endpoints / src / main / java / org / onap / policy / drools / http / server / internal / JettyJerseyServer.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * policy-endpoints
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20 package org.onap.policy.drools.http.server.internal;
21
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
24 import java.util.HashMap;
25
26 import org.eclipse.jetty.servlet.ServletHolder;
27 import org.slf4j.LoggerFactory;
28 import org.slf4j.Logger;
29
30 import io.swagger.jersey.config.JerseyJaxrsConfig;
31
32 /**
33  * REST Jetty Server that uses Jersey Servlets to support JAX-RS Web Services
34  */
35 public class JettyJerseyServer extends JettyServletServer {
36         
37         /**
38          * Jersey Packages Init Param Name
39          */
40         protected static final String JERSEY_INIT_PACKAGES_PARAM_NAME = "jersey.config.server.provider.packages";
41         
42         /**
43          * Jersey Packages Init Param Value
44          */
45         protected static final String JERSEY_INIT_PACKAGES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json";
46         
47         /**
48          * Swagger Packages
49          */
50         protected static final String SWAGGER_INIT_PACKAGES_PARAM_VALUE = "io.swagger.jaxrs.listing";
51         
52         /**
53          * Jersey Classes Init Param Name
54          */
55         protected static final String JERSEY_INIT_CLASSNAMES_PARAM_NAME = "jersey.config.server.provider.classnames";
56         
57         /**
58          * Jersey Jackson Classes Init Param Value
59          */
60         protected static final String JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE = "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider";
61         
62         /**
63          * Jersey Swagger Classes Init Param Value
64          */
65         protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE = "io.swagger.jaxrs.listing.ApiListingResource," +
66                                                                                                                                         "io.swagger.jaxrs.listing.SwaggerSerializers";
67         /**
68          * Logger
69          */
70         protected static Logger logger = LoggerFactory.getLogger(JettyJerseyServer.class);
71         
72         /**
73          * Container for servlets
74          */
75         protected HashMap<String, ServletHolder> servlets = new HashMap<String, ServletHolder>();
76         
77         /**
78          * Swagger ID
79          */
80         protected String swaggerId = null;
81         
82         /**
83          * Constructor
84          * 
85          * @param name name
86          * @param host host server host
87          * @param port port server port
88          * @param swagger support swagger?
89          * @param contextPath context path
90          * 
91          * @throws IllegalArgumentException in invalid arguments are provided
92          */
93         public JettyJerseyServer(String name, String host, int port, String contextPath, boolean swagger) 
94                throws IllegalArgumentException {
95                 
96                 super(name, host, port, contextPath);
97                 if (swagger) {
98                         this.swaggerId = "swagger-" + this.port;
99                         attachSwaggerServlet();
100                 }
101         }
102         
103         /**
104          * attaches a swagger initialization servlet
105          */
106         protected void attachSwaggerServlet() {
107                 
108                 ServletHolder swaggerServlet = context.addServlet(JerseyJaxrsConfig.class, "/");
109
110                 String hostname = this.connector.getHost();
111                 if (hostname == null || hostname.isEmpty() || hostname.equals("0.0.0.0")) {
112                         try {
113                                 hostname = InetAddress.getLocalHost().getHostName();
114                         } catch (UnknownHostException e) {
115                                 logger.warn("{}: can't resolve connector's hostname: ", this);
116                                 hostname = "localhost";
117                         }
118                 }
119
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);
126                 
127         if (logger.isDebugEnabled())
128                 logger.debug("{}: Swagger Servlet has been attached: {}", this, swaggerServlet.dump());
129         }       
130         
131         /**
132          * retrieves cached server based on servlet path
133          * 
134          * @param servletPath servlet path
135          * @return the jetty servlet holder
136          * 
137          * @throws IllegalArgumentException if invalid arguments are provided
138          */
139         protected synchronized ServletHolder getServlet(String servletPath)
140                           throws IllegalArgumentException {
141                 
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);
148                 }
149                 
150                 return jerseyServlet;
151         }
152         
153         @Override
154         public synchronized void addServletPackage(String servletPath, String restPackage) 
155                throws IllegalArgumentException, IllegalStateException {
156                 
157         if (restPackage == null || restPackage.isEmpty())
158                         throw new IllegalArgumentException("No discoverable REST package provided");
159         
160         if (servletPath == null || servletPath.isEmpty())
161                 servletPath = "/*";
162                 
163                 ServletHolder jerseyServlet = this.getServlet(servletPath);
164                 
165                 String initClasses = 
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);
169                 
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 + "," + 
176                                                        restPackage;
177                                 
178                         jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
179                         jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
180                         } else {
181                                 initPackages = JERSEY_INIT_PACKAGES_PARAM_VALUE + "," + 
182                                                restPackage;
183                         }
184                 } else {
185                         initPackages = initPackages + "," + restPackage;
186                 }
187                 
188         jerseyServlet.setInitParameter(JERSEY_INIT_PACKAGES_PARAM_NAME,  initPackages);
189         
190         if (logger.isDebugEnabled())
191                 logger.debug("{}: added REST package: {}", this, jerseyServlet.dump());
192         }
193         
194         @Override
195         public synchronized void addServletClass(String servletPath, String restClass) 
196                        throws IllegalArgumentException, IllegalStateException {
197                         
198         if (restClass == null || restClass.isEmpty())
199                         throw new IllegalArgumentException("No discoverable REST class provided");
200         
201         if (servletPath == null || servletPath.isEmpty())
202                 servletPath = "/*";
203                 
204                 ServletHolder jerseyServlet = this.getServlet(servletPath);
205                 
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);
210                 
211                 String initClasses = 
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 + "," + 
217                                               restClass;
218                                 
219                         jerseyServlet.setInitParameter("swagger.context.id", swaggerId);
220                         jerseyServlet.setInitParameter("swagger.scanner.id", swaggerId);
221                         } else {
222                                 initClasses = JERSEY_JACKSON_INIT_CLASSNAMES_PARAM_VALUE + "," + restClass;
223                         }                       
224                 } else {
225                         initClasses = initClasses + "," + restClass;
226                 }
227                 
228         jerseyServlet.setInitParameter(JERSEY_INIT_CLASSNAMES_PARAM_NAME, initClasses);
229         
230         if (logger.isDebugEnabled())
231                 logger.debug("{}: added REST class: {}", this, jerseyServlet.dump());
232         }
233         
234         @Override
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();
240         }
241 }