c789cd26ea4324df7654662f288b6938e59bbba6
[policy/common.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * policy-endpoints
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
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
21 package org.onap.policy.common.endpoints.http.server;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Properties;
28 import org.onap.aaf.cadi.filter.CadiFilter;
29 import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer;
30 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * Factory of HTTP Servlet-Enabled Servlets.
36  */
37 public interface HttpServletServerFactory {
38
39     /**
40      * Builds an http or https server with support for servlets.
41      * 
42      * @param name name
43      * @param https use secured http over tls connection
44      * @param host binding host
45      * @param port port
46      * @param contextPath server base path
47      * @param swagger enable swagger documentation
48      * @param managed is it managed by infrastructure
49      * @return http server
50      * @throws IllegalArgumentException when invalid parameters are provided
51      */
52     HttpServletServer build(String name, boolean https, String host, int port, String contextPath, boolean swagger,
53             boolean managed);
54
55     /**
56      * Builds an http server with support for servlets.
57      *
58      * @param name name
59      * @param host binding host
60      * @param port port
61      * @param contextPath server base path
62      * @param swagger enable swagger documentation
63      * @param managed is it managed by infrastructure
64      * @return http server
65      * @throws IllegalArgumentException when invalid parameters are provided
66      */
67     HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger,
68         boolean managed);
69
70     /**
71      * Build a list of http servers per properties.
72      * 
73      * @param properties properties based configuration
74      * @return list of http servers
75      * @throws IllegalArgumentException when invalid parameters are provided
76      */
77     List<HttpServletServer> build(Properties properties);
78
79     /**
80      * Gets a server based on the port.
81      * 
82      * @param port port
83      * @return http server
84      */
85     HttpServletServer get(int port);
86
87     /**
88      * Provides an inventory of servers.
89      * 
90      * @return inventory of servers
91      */
92     List<HttpServletServer> inventory();
93
94     /**
95      * Destroys server bound to a port.
96      * 
97      * @param port the port the server is bound to
98      */
99     void destroy(int port);
100
101     /**
102      * Destroys the factory and therefore all servers.
103      */
104     void destroy();
105 }
106
107
108 /**
109  * Indexed factory implementation.
110  */
111 class IndexedHttpServletServerFactory implements HttpServletServerFactory {
112
113     private static final String SPACES_COMMA_SPACES = "\\s*,\\s*";
114
115     /**
116      * logger.
117      */
118     protected static Logger logger = LoggerFactory.getLogger(IndexedHttpServletServerFactory.class);
119
120     /**
121      * servers index.
122      */
123     protected HashMap<Integer, HttpServletServer> servers = new HashMap<>();
124
125     @Override
126     public synchronized HttpServletServer build(String name, boolean https, 
127                     String host, int port, String contextPath, boolean swagger,
128             boolean managed) {
129
130         if (servers.containsKey(port)) {
131             return servers.get(port);
132         }
133
134         JettyJerseyServer server = new JettyJerseyServer(name, https, host, port, contextPath, swagger);
135         if (managed) {
136             servers.put(port, server);
137         }
138
139         return server;
140     }
141
142     @Override
143     public synchronized HttpServletServer build(String name, String host, int port, String contextPath,
144                                                 boolean swagger, boolean managed) {
145         return build(name, false, host, port, contextPath, swagger, managed);
146     }
147
148
149     @Override
150     public synchronized List<HttpServletServer> build(Properties properties) {
151
152         ArrayList<HttpServletServer> serviceList = new ArrayList<>();
153
154         String serviceNames = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES);
155         if (serviceNames == null || serviceNames.isEmpty()) {
156             logger.warn("No topic for HTTP Service: {}", properties);
157             return serviceList;
158         }
159
160         List<String> serviceNameList = Arrays.asList(serviceNames.split(SPACES_COMMA_SPACES));
161
162         for (String serviceName : serviceNameList) {
163             String servicePortString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES
164                     + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX);
165
166             int servicePort;
167             try {
168                 if (servicePortString == null || servicePortString.isEmpty()) {
169                     if (logger.isWarnEnabled()) {
170                         logger.warn("No HTTP port for service in {}", serviceName);
171                     }
172                     continue;
173                 }
174                 servicePort = Integer.parseInt(servicePortString);
175             } catch (NumberFormatException nfe) {
176                 if (logger.isWarnEnabled()) {
177                     logger.warn("No HTTP port for service in {}", serviceName);
178                 }
179                 continue;
180             }
181
182             String hostName = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
183                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX);
184
185             String contextUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
186                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX);
187
188             String userName = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
189                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX);
190
191             String password = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
192                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX);
193
194             String authUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
195                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_URIPATH_SUFFIX);
196
197             String restClasses = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
198                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX);
199
200             String filterClasses = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
201                 + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX);
202
203             String restPackages = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
204                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_PACKAGES_SUFFIX);
205             String restUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
206                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX);
207
208             String managedString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
209                     + serviceName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX);
210             boolean managed = true;
211             if (managedString != null && !managedString.isEmpty()) {
212                 managed = Boolean.parseBoolean(managedString);
213             }
214
215             String swaggerString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
216                     + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX);
217             boolean swagger = false;
218             if (swaggerString != null && !swaggerString.isEmpty()) {
219                 swagger = Boolean.parseBoolean(swaggerString);
220             }
221
222             String httpsString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
223                 + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX);
224             boolean https = false;
225             if (httpsString != null && !httpsString.isEmpty()) {
226                 https = Boolean.parseBoolean(httpsString);
227             }
228
229             String aafString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "."
230                 + serviceName + PolicyEndPointProperties.PROPERTY_AAF_SUFFIX);
231             boolean aaf = false;
232             if (aafString != null && !aafString.isEmpty()) {
233                 aaf = Boolean.parseBoolean(httpsString);
234             }
235
236             HttpServletServer service = build(serviceName, https, hostName, servicePort, contextUriPath, swagger, managed);
237
238             /* authentication method either AAF or HTTP Basic Auth */
239
240             if (aaf) {
241                 service.addFilterClass(contextUriPath, CadiFilter.class.getCanonicalName());
242             } else if (userName != null && !userName.isEmpty() && password != null && !password.isEmpty()) {
243                     service.setBasicAuthentication(userName, password, authUriPath);
244             }
245
246             if (filterClasses != null && !filterClasses.isEmpty()) {
247                 List<String> filterClassesList = Arrays.asList(filterClasses.split(SPACES_COMMA_SPACES));
248                 for (String filterClass : filterClassesList) {
249                     service.addFilterClass(restUriPath, filterClass);
250                 }
251             }
252
253             if (restClasses != null && !restClasses.isEmpty()) {
254                 List<String> restClassesList = Arrays.asList(restClasses.split(SPACES_COMMA_SPACES));
255                 for (String restClass : restClassesList) {
256                     service.addServletClass(restUriPath, restClass);
257                 }
258             }
259
260             if (restPackages != null && !restPackages.isEmpty()) {
261                 List<String> restPackageList = Arrays.asList(restPackages.split(SPACES_COMMA_SPACES));
262                 for (String restPackage : restPackageList) {
263                     service.addServletPackage(restUriPath, restPackage);
264                 }
265             }
266
267
268             serviceList.add(service);
269         }
270
271         return serviceList;
272     }
273
274     @Override
275     public synchronized HttpServletServer get(int port) {
276
277         if (servers.containsKey(port)) {
278             return servers.get(port);
279         }
280
281         throw new IllegalArgumentException("Http Server for " + port + " not found");
282     }
283
284     @Override
285     public synchronized List<HttpServletServer> inventory() {
286         return new ArrayList<>(this.servers.values());
287     }
288
289     @Override
290     public synchronized void destroy(int port) {
291
292         if (!servers.containsKey(port)) {
293             return;
294         }
295
296         HttpServletServer server = servers.remove(port);
297         server.shutdown();
298     }
299
300     @Override
301     public synchronized void destroy() {
302         List<HttpServletServer> httpServletServers = this.inventory();
303         for (HttpServletServer server : httpServletServers) {
304             server.shutdown();
305         }
306
307         synchronized (this) {
308             this.servers.clear();
309         }
310     }
311
312 }