2 * ============LICENSE_START=======================================================
3 * ONAP Policy Engine - Common Modules
4 * ================================================================================
5 * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2020,2023-2024 Nordix Foundation.
7 * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.common.endpoints.http.server;
25 import com.google.re2j.Pattern;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Properties;
30 import org.apache.commons.lang3.StringUtils;
31 import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer;
32 import org.onap.policy.common.endpoints.http.server.internal.JettyStaticResourceServer;
33 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
34 import org.onap.policy.common.endpoints.utils.PropertyUtils;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Indexed factory implementation.
41 class IndexedHttpServletServerFactory implements HttpServletServerFactory {
42 private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*");
47 protected static Logger logger = LoggerFactory.getLogger(IndexedHttpServletServerFactory.class);
52 protected HashMap<Integer, HttpServletServer> servers = new HashMap<>();
55 public synchronized HttpServletServer build(String name, boolean https, String host, int port, boolean sniHostCheck,
56 String contextPath, boolean swagger, boolean managed) {
58 if (servers.containsKey(port)) {
59 return servers.get(port);
62 var server = new JettyJerseyServer(name, https, host, port, sniHostCheck, contextPath, swagger);
64 servers.put(port, server);
71 public synchronized HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger,
73 return build(name, false, host, port, false, contextPath, swagger, managed);
77 public synchronized List<HttpServletServer> build(Properties properties) {
79 ArrayList<HttpServletServer> serviceList = new ArrayList<>();
81 String serviceNames = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES);
82 if (StringUtils.isBlank(serviceNames)) {
83 logger.warn("No topic for HTTP Service: {}", properties);
87 for (String serviceName : COMMA_SPACE_PAT.split(serviceNames)) {
88 addService(serviceList, serviceName, properties);
95 public HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port,
96 boolean sniHostCheck, String contextPath, boolean managed) {
97 if (servers.containsKey(port)) {
98 return servers.get(port);
101 var server = new JettyStaticResourceServer(name, https, host, port, sniHostCheck, contextPath);
103 servers.put(port, server);
109 private void addService(ArrayList<HttpServletServer> serviceList, String serviceName, Properties properties) {
111 String servicePrefix = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + serviceName;
113 var props = new PropertyUtils(properties, servicePrefix,
114 (name, value, ex) -> logger
115 .warn("{}: {} {} is in invalid format for http service {} ", this, name, value, serviceName));
117 var servicePort = props.getInteger(PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, -1);
118 if (servicePort < 0) {
119 logger.warn("No HTTP port for service in {}", serviceName);
123 final var hostName = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, null);
124 final var contextUriPath = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX, null);
125 var managed = props.getBoolean(PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, true);
126 var swagger = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, false);
127 var https = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, false);
128 var sniHostCheck = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_SNI_HOST_CHECK_SUFFIX, false);
130 // create the service
131 HttpServletServer service =
132 build(serviceName, https, hostName, servicePort, sniHostCheck, contextUriPath, swagger, managed);
134 // configure the service
135 setSerializationProvider(props, service);
136 setAuthentication(props, service);
138 final var restUriPath = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX, null);
140 addFilterClasses(props, service, restUriPath);
141 addRestServletClasses(props, service, restUriPath);
142 addServletPackages(props, service, restUriPath);
144 addServletClass(props, service);
145 setPrometheus(props, service);
147 serviceList.add(service);
150 private void setSerializationProvider(PropertyUtils props, HttpServletServer service) {
152 final var classProv = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, null);
154 if (!StringUtils.isBlank(classProv)) {
155 service.setSerializationProvider(classProv);
159 private void setAuthentication(PropertyUtils props, HttpServletServer service) {
160 /* authentication method HTTP Basic Auth */
161 final var userName = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, null);
162 final var password = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX, null);
163 final var authUriPath = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_AUTH_URIPATH_SUFFIX, null);
165 if (!StringUtils.isBlank(userName) && !StringUtils.isBlank(password)) {
166 service.setBasicAuthentication(userName, password, authUriPath);
170 private void setPrometheus(PropertyUtils props, HttpServletServer service) {
171 if (props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_PROMETHEUS_SUFFIX, false)) {
172 service.setPrometheus("/metrics");
176 private void addFilterClasses(PropertyUtils props, HttpServletServer service, final String restUriPath) {
178 final var filterClasses =
179 props.getString(PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX, null);
181 if (!StringUtils.isBlank(filterClasses)) {
182 for (String filterClass : COMMA_SPACE_PAT.split(filterClasses)) {
183 service.addFilterClass(restUriPath, filterClass);
188 private void addRestServletClasses(PropertyUtils props, HttpServletServer service, final String restUriPath) {
189 final var restClasses = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, null);
191 if (!StringUtils.isBlank(restClasses)) {
192 for (String restClass : COMMA_SPACE_PAT.split(restClasses)) {
193 service.addServletClass(restUriPath, restClass);
198 private void addServletClass(PropertyUtils props, HttpServletServer service) {
199 var servletClass = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_SERVLET_CLASS_SUFFIX, null);
200 var servletUriPath = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_SERVLET_URIPATH_SUFFIX, null);
202 if (!StringUtils.isBlank(servletClass) && !StringUtils.isBlank(servletUriPath)) {
203 service.addStdServletClass(servletUriPath, servletClass);
207 private void addServletPackages(PropertyUtils props, HttpServletServer service, final String restUriPath) {
209 final var restPackages = props.getString(PolicyEndPointProperties.PROPERTY_HTTP_REST_PACKAGES_SUFFIX, null);
211 if (!StringUtils.isBlank(restPackages)) {
212 for (String restPackage : COMMA_SPACE_PAT.split(restPackages)) {
213 service.addServletPackage(restUriPath, restPackage);
219 public synchronized HttpServletServer get(int port) {
221 if (servers.containsKey(port)) {
222 return servers.get(port);
225 throw new IllegalArgumentException("Http Server for " + port + " not found");
229 public synchronized List<HttpServletServer> inventory() {
230 return new ArrayList<>(this.servers.values());
234 public synchronized void destroy(int port) {
236 if (!servers.containsKey(port)) {
240 HttpServletServer server = servers.remove(port);
245 public synchronized void destroy() {
246 List<HttpServletServer> httpServletServers = this.inventory();
247 for (HttpServletServer server : httpServletServers) {
251 synchronized (this) {
252 this.servers.clear();