aboutsummaryrefslogtreecommitdiffstats
path: root/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java
diff options
context:
space:
mode:
Diffstat (limited to 'policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java')
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java209
1 files changed, 117 insertions, 92 deletions
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java
index 133adade..78858a77 100644
--- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java
@@ -2,7 +2,9 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020, 2023-2024 Nordix Foundation.
+ * Modifications Copyright (C) 2020-2021 Bell Canada. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +22,15 @@
package org.onap.policy.common.endpoints.http.server.internal;
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.prometheus.client.hotspot.DefaultExports;
+import io.prometheus.client.servlet.jakarta.exporter.MetricsServlet;
+import jakarta.servlet.Servlet;
import java.util.EnumSet;
-import javax.servlet.DispatcherType;
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
@@ -35,58 +43,70 @@ import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.Slf4jRequestLogWriter;
-import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.onap.aaf.cadi.filter.CadiFilter;
import org.onap.policy.common.endpoints.http.server.HttpServletServer;
-import org.onap.policy.common.gson.annotation.GsonJsonIgnore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Http Server implementation using Embedded Jetty.
*/
+@ToString
public abstract class JettyServletServer implements HttpServletServer, Runnable {
/**
* Keystore/Truststore system property names.
*/
public static final String SYSTEM_KEYSTORE_PROPERTY_NAME = "javax.net.ssl.keyStore";
- public static final String SYSTEM_KEYSTORE_PASSWORD_PROPERTY_NAME = "javax.net.ssl.keyStorePassword"; //NOSONAR
+ public static final String SYSTEM_KEYSTORE_PASSWORD_PROPERTY_NAME = "javax.net.ssl.keyStorePassword"; // NOSONAR
public static final String SYSTEM_TRUSTSTORE_PROPERTY_NAME = "javax.net.ssl.trustStore";
- public static final String SYSTEM_TRUSTSTORE_PASSWORD_PROPERTY_NAME = "javax.net.ssl.trustStorePassword"; //NOSONAR
+ public static final String SYSTEM_TRUSTSTORE_PASSWORD_PROPERTY_NAME = "javax.net.ssl.trustStorePassword"; // NOSONAR
/**
* Logger.
*/
- private static Logger logger = LoggerFactory.getLogger(JettyServletServer.class);
+ private static final Logger logger = LoggerFactory.getLogger(JettyServletServer.class);
+
+ private static final String NOT_SUPPORTED = " is not supported on this type of jetty server";
/**
* Server name.
*/
+ @Getter
protected final String name;
/**
* Server host address.
*/
+ @Getter
protected final String host;
/**
* Server port to bind.
*/
+ @Getter
protected final int port;
/**
- * Server auth user name.
+ * Should SNI host checking be done.
+ */
+ @Getter
+ protected boolean sniHostCheck;
+
+ /**
+ * Server auth username.
*/
+ @Getter
protected String user;
/**
* Server auth password name.
*/
+ @Getter
protected String password;
/**
@@ -112,12 +132,18 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
/**
* Jetty thread.
*/
- protected volatile Thread jettyThread;
+ protected Thread jettyThread;
+
+ /**
+ * Container for default servlets.
+ */
+ protected final Map<String, ServletHolder> servlets = new HashMap<>();
/**
* Start condition.
*/
- protected Object startCondition = new Object();
+ @ToString.Exclude
+ protected final Object startCondition = new Object();
/**
* Constructor.
@@ -125,11 +151,13 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
* @param name server name
* @param host server host
* @param port server port
+ * @param sniHostCheck SNI Host checking flag
* @param contextPath context path
*
* @throws IllegalArgumentException if invalid parameters are passed in
*/
- public JettyServletServer(String name, boolean https, String host, int port, String contextPath) {
+ protected JettyServletServer(String name, boolean https, String host, int port, boolean sniHostCheck,
+ String contextPath) {
String srvName = name;
if (srvName == null || srvName.isEmpty()) {
@@ -154,6 +182,7 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
this.host = srvHost;
this.port = port;
+ this.sniHostCheck = sniHostCheck;
this.contextPath = ctxtPath;
@@ -162,8 +191,7 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
this.jettyServer = new Server();
- CustomRequestLog requestLog =
- new CustomRequestLog(new Slf4jRequestLogWriter(), CustomRequestLog.EXTENDED_NCSA_FORMAT);
+ var requestLog = new CustomRequestLog(new Slf4jRequestLogWriter(), CustomRequestLog.EXTENDED_NCSA_FORMAT);
this.jettyServer.setRequestLog(requestLog);
if (https) {
@@ -181,8 +209,8 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
this.jettyServer.setHandler(context);
}
- public JettyServletServer(String name, String host, int port, String contextPath) {
- this(name, false, host, port, contextPath);
+ protected JettyServletServer(String name, String host, int port, boolean sniHostCheck, String contextPath) {
+ this(name, false, host, port, sniHostCheck, contextPath);
}
@Override
@@ -196,7 +224,20 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
tempFilterPath = "/*";
}
- context.addFilter(filterClass, tempFilterPath, EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
+ context.addFilter(filterClass, tempFilterPath,
+ EnumSet.of(jakarta.servlet.DispatcherType.INCLUDE, jakarta.servlet.DispatcherType.REQUEST));
+ }
+
+ protected ServletHolder getServlet(@NonNull Class<? extends Servlet> servlet, @NonNull String servletPath) {
+ synchronized (servlets) {
+ return servlets.computeIfAbsent(servletPath, key -> context.addServlet(servlet, servletPath));
+ }
+ }
+
+ protected ServletHolder getServlet(String servletClass, String servletPath) {
+ synchronized (servlets) {
+ return servlets.computeIfAbsent(servletPath, key -> context.addServlet(servletClass, servletPath));
+ }
}
/**
@@ -205,32 +246,35 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
* @return the server connector
*/
public ServerConnector httpsConnector() {
- SslContextFactory sslContextFactory = new SslContextFactory.Server();
+ SslContextFactory.Server sslContextFactoryServer = new SslContextFactory.Server();
String keyStore = System.getProperty(SYSTEM_KEYSTORE_PROPERTY_NAME);
if (keyStore != null) {
- sslContextFactory.setKeyStorePath(keyStore);
+ sslContextFactoryServer.setKeyStorePath(keyStore);
String ksPassword = System.getProperty(SYSTEM_KEYSTORE_PASSWORD_PROPERTY_NAME);
if (ksPassword != null) {
- sslContextFactory.setKeyStorePassword(ksPassword);
+ sslContextFactoryServer.setKeyStorePassword(ksPassword);
}
}
String trustStore = System.getProperty(SYSTEM_TRUSTSTORE_PROPERTY_NAME);
if (trustStore != null) {
- sslContextFactory.setTrustStorePath(trustStore);
+ sslContextFactoryServer.setTrustStorePath(trustStore);
String tsPassword = System.getProperty(SYSTEM_TRUSTSTORE_PASSWORD_PROPERTY_NAME);
if (tsPassword != null) {
- sslContextFactory.setTrustStorePassword(tsPassword);
+ sslContextFactoryServer.setTrustStorePassword(tsPassword);
}
}
- HttpConfiguration https = new HttpConfiguration();
- https.addCustomizer(new SecureRequestCustomizer());
- return new ServerConnector(jettyServer, sslContextFactory, new HttpConnectionFactory(https));
+ var httpsConfiguration = new HttpConfiguration();
+ SecureRequestCustomizer src = new SecureRequestCustomizer();
+ src.setSniHostCheck(sniHostCheck);
+ httpsConfiguration.addCustomizer(src);
+
+ return new ServerConnector(jettyServer, sslContextFactoryServer, new HttpConnectionFactory(httpsConfiguration));
}
public ServerConnector httpConnector() {
@@ -238,21 +282,6 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
}
@Override
- public void setAafAuthentication(String filterPath) {
- this.addFilterClass(filterPath, CadiFilter.class.getName());
- }
-
- @Override
- public boolean isAaf() {
- for (FilterHolder filter : context.getServletHandler().getFilters()) {
- if (CadiFilter.class.getName().equals(filter.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
- @Override
public void setBasicAuthentication(String user, String password, String servletPath) {
String srvltPath = servletPath;
@@ -264,22 +293,26 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
srvltPath = "/*";
}
- final HashLoginService hashLoginService = new HashLoginService();
- final UserStore userStore = new UserStore();
- userStore.addUser(user, Credential.getCredential(password), new String[] {"user"});
+ final var hashLoginService = new HashLoginService();
+ final var userStore = new UserStore();
+ userStore.addUser(user, Credential.getCredential(password), new String[] {
+ "user"
+ });
hashLoginService.setUserStore(userStore);
hashLoginService.setName(this.connector.getName() + "-login-service");
- Constraint constraint = new Constraint();
+ var constraint = new Constraint();
constraint.setName(Constraint.__BASIC_AUTH);
- constraint.setRoles(new String[] {"user"});
+ constraint.setRoles(new String[] {
+ "user"
+ });
constraint.setAuthenticate(true);
- ConstraintMapping constraintMapping = new ConstraintMapping();
+ var constraintMapping = new ConstraintMapping();
constraintMapping.setConstraint(constraint);
constraintMapping.setPathSpec(srvltPath);
- ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
+ var securityHandler = new ConstraintSecurityHandler();
securityHandler.setAuthenticator(new BasicAuthenticator());
securityHandler.setRealmName(this.connector.getName() + "-realm");
securityHandler.addConstraintMapping(constraintMapping);
@@ -310,6 +343,11 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
}
this.jettyServer.join();
+
+ } catch (InterruptedException e) {
+ logger.error("{}: error found while bringing up server", this, e);
+ Thread.currentThread().interrupt();
+
} catch (Exception e) {
logger.error("{}: error found while bringing up server", this, e);
}
@@ -415,12 +453,13 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
this.stop();
- if (this.jettyThread == null) {
- return;
+ Thread jettyThreadCopy;
+ synchronized (this) {
+ if ((jettyThreadCopy = this.jettyThread) == null) {
+ return;
+ }
}
- Thread jettyThreadCopy = this.jettyThread;
-
if (jettyThreadCopy.isAlive()) {
try {
jettyThreadCopy.join(2000L);
@@ -451,58 +490,44 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
}
@Override
- public int getPort() {
- return this.port;
+ public void setSerializationProvider(String provider) {
+ throw new UnsupportedOperationException("setSerializationProvider()" + NOT_SUPPORTED);
}
- /**
- * Get name.
- *
- * @return the name
- */
@Override
- public String getName() {
- return name;
+ public void addServletClass(String servletPath, String servletClass) {
+ throw new UnsupportedOperationException("addServletClass()" + NOT_SUPPORTED);
}
- /**
- * Get host.
- *
- * @return the host
- */
- public String getHost() {
- return host;
+ @Override
+ public void addStdServletClass(@NonNull String servletPath, @NonNull String plainServletClass) {
+ this.getServlet(plainServletClass, servletPath);
}
- /**
- * Get user.
- *
- * @return the user
- */
- public String getUser() {
- return user;
+ @Override
+ public void setPrometheus(String metricsPath) {
+ this.getServlet(MetricsServlet.class, metricsPath);
+ DefaultExports.initialize();
}
- /**
- * Get password.
- *
- * @return the password
- */
- @JsonIgnore
- @GsonJsonIgnore
- public String getPassword() {
- return password;
+ @Override
+ public boolean isPrometheus() {
+ for (ServletHolder servlet : context.getServletHandler().getServlets()) {
+ if (MetricsServlet.class.getName().equals(servlet.getClassName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void addServletPackage(String servletPath, String restPackage) {
+ throw new UnsupportedOperationException("addServletPackage()" + NOT_SUPPORTED);
}
@Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("JettyServer [name=").append(name).append(", host=").append(host).append(", port=").append(port)
- .append(", user=").append(user).append(", password=").append(password != null).append(", contextPath=")
- .append(contextPath).append(", jettyServer=").append(jettyServer).append(", context=")
- .append(this.context).append(", connector=").append(connector).append(", jettyThread=")
- .append(jettyThread).append("]");
- return builder.toString();
+ public void addServletResource(String servletPath, String resourceBase) {
+ throw new UnsupportedOperationException("addServletResource()" + NOT_SUPPORTED);
}
}