Upgrade Jetty and Jersey 57/133657/1
authorliamfallon <liam.fallon@est.tech>
Tue, 14 Mar 2023 17:00:37 +0000 (17:00 +0000)
committerLiam Fallon <liam.fallon@est.tech>
Tue, 14 Mar 2023 17:28:36 +0000 (17:28 +0000)
The new version of Jetty and Jersey brings in Server Name Checking,
which must be eiter enabled or disabled.

Also, the bug in Swagger that drags in JUnit 5 with a non "test" scope is
worked around by excluding the junit 5 dependencies.

Issue-ID: POLICY-4474
Change-Id: Ib5ba23616c8d3cb011c5055a49c9cb325c9fd667
Signed-off-by: liamfallon <liam.fallon@est.tech>
12 files changed:
policy-endpoints/pom.xml
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/HttpServletServerFactory.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/IndexedHttpServletServerFactory.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyJerseyServer.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyServletServer.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/internal/JettyStaticResourceServer.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestServerParameters.java
policy-endpoints/src/main/java/org/onap/policy/common/endpoints/properties/PolicyEndPointProperties.java
policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpClientTest.java
policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java
policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/http/server/internal/HttpServerTest.json

index b7fb88a..4665ccc 100644 (file)
   SPDX-License-Identifier: Apache-2.0
   ============LICENSE_END=========================================================
 -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
+<project
+        xmlns="http://maven.apache.org/POM/4.0.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                            http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
-
     <parent>
         <groupId>org.onap.policy.common</groupId>
         <artifactId>common-modules</artifactId>
         <version>1.12.2-SNAPSHOT</version>
     </parent>
-
     <artifactId>policy-endpoints</artifactId>
-
     <name>policy-endpoints</name>
     <description>Endpoints</description>
-
     <properties>
         <cambria.version>1.2.1-oss</cambria.version>
     </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.onap.policy.common</groupId>
             <artifactId>capabilities</artifactId>
             <version>${project.version}</version>
         </dependency>
-
         <dependency>
             <groupId>org.onap.policy.common</groupId>
             <artifactId>gson</artifactId>
             <version>${project.version}</version>
         </dependency>
-
         <dependency>
             <groupId>org.onap.policy.common</groupId>
             <artifactId>utils</artifactId>
             <version>${project.version}</version>
         </dependency>
-
         <dependency>
             <groupId>org.onap.policy.common</groupId>
             <artifactId>common-parameters</artifactId>
             <version>${project.version}</version>
         </dependency>
-
         <dependency>
             <groupId>com.att.nsa</groupId>
             <artifactId>cambriaClient</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
-
         <!-- needed by glassfish jersey which is needed by dmaap -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-core</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.fasterxml.jackson.module</groupId>
             <artifactId>jackson-module-jaxb-annotations</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.fasterxml.jackson.dataformat</groupId>
             <artifactId>jackson-dataformat-yaml</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.onap.dmaap.messagerouter.dmaapclient</groupId>
             <artifactId>dmaapClient</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.onap.aaf.authz</groupId>
             <artifactId>aaf-cadi-aaf</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-server</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-servlet</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-servlets</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-server</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.containers</groupId>
             <artifactId>jersey-container-servlet-core</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.containers</groupId>
             <artifactId>jersey-container-jetty-http</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-client</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-common</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpcore</artifactId>
         </dependency>
-
         <dependency>
             <groupId>io.swagger</groupId>
             <artifactId>swagger-jersey2-jaxrs</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
-
         <dependency>
             <groupId>io.prometheus</groupId>
             <artifactId>simpleclient_hotspot</artifactId>
         </dependency>
-
         <dependency>
             <groupId>io.prometheus</groupId>
             <artifactId>simpleclient_servlet</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-collections4</artifactId>
         </dependency>
-
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.onap.policy.common</groupId>
             <artifactId>utils-test</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.inject</groupId>
             <artifactId>jersey-hk2</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.openpojo</groupId>
             <artifactId>openpojo</artifactId>
         </dependency>
-
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <scope>provided</scope>
         </dependency>
-
-         <dependency>
+        <dependency>
             <groupId>org.apache.kafka</groupId>
             <artifactId>kafka-clients</artifactId>
             <scope>provided</scope>
index 90c0db2..4aecd1e 100644 (file)
@@ -3,7 +3,7 @@
  * policy-endpoints
  * ================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2020,2023 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,14 +36,15 @@ public interface HttpServletServerFactory {
      * @param https use secured http over tls connection
      * @param host binding host
      * @param port port
+     * @param sniHostCheck SNI Host checking flag
      * @param contextPath server base path
      * @param swagger enable swagger documentation
      * @param managed is it managed by infrastructure
      * @return http server
      * @throws IllegalArgumentException when invalid parameters are provided
      */
-    HttpServletServer build(String name, boolean https, String host, int port, String contextPath, boolean swagger,
-        boolean managed);
+    HttpServletServer build(String name, boolean https, String host, int port, boolean sniHostCheck, String contextPath,
+        boolean swagger, boolean managed);
 
     /**
      * Builds an http rest server with support for servlets.
@@ -75,13 +76,14 @@ public interface HttpServletServerFactory {
      * @param https use secured http over tls connection
      * @param host binding host
      * @param port port
+     * @param sniHostCheck SNI Host checking flag
      * @param contextPath server base path
      * @param managed is it managed by infrastructure
      * @return http server
      * @throws IllegalArgumentException when invalid parameters are provided
      */
-    HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port, String contextPath,
-            boolean managed);
+    HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port, boolean sniHostCheck,
+        String contextPath, boolean managed);
 
     /**
      * Gets a server based on the port.
index 86f5fb0..2f55794 100644 (file)
@@ -3,7 +3,7 @@
  * ONAP Policy Engine - Common Modules
  * ================================================================================
  * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2020,2023 Nordix Foundation.
  * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -52,14 +52,14 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
     protected HashMap<Integer, HttpServletServer> servers = new HashMap<>();
 
     @Override
-    public synchronized HttpServletServer build(String name, boolean https, String host, int port, String contextPath,
-        boolean swagger, boolean managed) {
+    public synchronized HttpServletServer build(String name, boolean https, String host, int port, boolean sniHostCheck,
+        String contextPath, boolean swagger, boolean managed) {
 
         if (servers.containsKey(port)) {
             return servers.get(port);
         }
 
-        var server = new JettyJerseyServer(name, https, host, port, contextPath, swagger);
+        var server = new JettyJerseyServer(name, https, host, port, sniHostCheck, contextPath, swagger);
         if (managed) {
             servers.put(port, server);
         }
@@ -70,7 +70,7 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
     @Override
     public synchronized HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger,
         boolean managed) {
-        return build(name, false, host, port, contextPath, swagger, managed);
+        return build(name, false, host, port, false, contextPath, swagger, managed);
     }
 
     @Override
@@ -91,16 +91,14 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
         return serviceList;
     }
 
-
-
     @Override
     public HttpServletServer buildStaticResourceServer(String name, boolean https, String host, int port,
-            String contextPath, boolean managed) {
+        boolean sniHostCheck, String contextPath, boolean managed) {
         if (servers.containsKey(port)) {
             return servers.get(port);
         }
 
-        var server = new JettyStaticResourceServer(name, https, host, port, contextPath);
+        var server = new JettyStaticResourceServer(name, https, host, port, sniHostCheck, contextPath);
         if (managed) {
             servers.put(port, server);
         }
@@ -114,7 +112,7 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
 
         var props = new PropertyUtils(properties, servicePrefix,
             (name, value, ex) -> logger
-                        .warn("{}: {} {} is in invalid format for http service {} ", this, name, value, serviceName));
+                .warn("{}: {} {} is in invalid format for http service {} ", this, name, value, serviceName));
 
         var servicePort = props.getInteger(PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, -1);
         if (servicePort < 0) {
@@ -127,9 +125,11 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
         var managed = props.getBoolean(PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, true);
         var swagger = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, false);
         var https = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX, false);
+        var sniHostCheck = props.getBoolean(PolicyEndPointProperties.PROPERTY_HTTP_SNI_HOST_CHECK_SUFFIX, false);
 
         // create the service
-        HttpServletServer service = build(serviceName, https, hostName, servicePort, contextUriPath, swagger, managed);
+        HttpServletServer service =
+            build(serviceName, https, hostName, servicePort, sniHostCheck, contextUriPath, swagger, managed);
 
         // configure the service
         setSerializationProvider(props, service);
@@ -180,7 +180,7 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory {
     private void addFilterClasses(PropertyUtils props, HttpServletServer service, final String restUriPath) {
 
         final var filterClasses =
-                        props.getString(PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX, null);
+            props.getString(PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX, null);
 
         if (!StringUtils.isBlank(filterClasses)) {
             for (String filterClass : COMMA_SPACE_PAT.split(filterClasses)) {
index 133a1e7..3301aec 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019,2023 Nordix Foundation.
  *  Modifications Copyright (C) 2019-2021 AT&T Intellectual Property.
  *  Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
  * ================================================================================
@@ -58,7 +58,7 @@ public class RestServer extends ServiceManagerContainer {
      * @param jaxrsProviders classes providing the services
      */
     public RestServer(final RestServerParameters restServerParameters, Class<? extends AafAuthFilter> aafFilter,
-                    Class<?>... jaxrsProviders) {
+        Class<?>... jaxrsProviders) {
 
         this(restServerParameters, makeFilterList(aafFilter), Arrays.asList(jaxrsProviders));
     }
@@ -79,14 +79,14 @@ public class RestServer extends ServiceManagerContainer {
      * @param jaxrsProviders classes providing the services
      */
     public RestServer(final RestServerParameters restServerParameters, List<Class<? extends Filter>> filters,
-                    List<Class<?>> jaxrsProviders) {
+        List<Class<?>> jaxrsProviders) {
 
         if (jaxrsProviders.isEmpty()) {
             throw new IllegalArgumentException("no providers specified");
         }
 
         this.servers = factory.getServerFactory()
-                        .build(getServerProperties(restServerParameters, getProviderClassNames(jaxrsProviders)));
+            .build(getServerProperties(restServerParameters, getProviderClassNames(jaxrsProviders)));
 
         for (HttpServletServer server : this.servers) {
             for (Class<? extends Filter> filter : filters) {
@@ -112,11 +112,11 @@ public class RestServer extends ServiceManagerContainer {
         props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, restServerParameters.getName());
 
         final String svcpfx =
-                        PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + restServerParameters.getName();
+            PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + restServerParameters.getName();
 
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, restServerParameters.getHost());
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX,
-                        Integer.toString(restServerParameters.getPort()));
+            Integer.toString(restServerParameters.getPort()));
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, names);
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "false");
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "true");
@@ -125,12 +125,14 @@ public class RestServer extends ServiceManagerContainer {
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX,
             getValue(restServerParameters.getPassword()));
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX,
-                        String.valueOf(restServerParameters.isHttps()));
+            String.valueOf(restServerParameters.isHttps()));
+        props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SNI_HOST_CHECK_SUFFIX,
+            String.valueOf(restServerParameters.isSniHostCHeck()));
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_AAF_SUFFIX,
-                        String.valueOf(restServerParameters.isAaf()));
+            String.valueOf(restServerParameters.isAaf()));
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
-                        String.join(",", GsonMessageBodyHandler.class.getName(), YamlMessageBodyHandler.class.getName(),
-                                        JsonExceptionMapper.class.getName(), YamlExceptionMapper.class.getName()));
+            String.join(",", GsonMessageBodyHandler.class.getName(), YamlMessageBodyHandler.class.getName(),
+                JsonExceptionMapper.class.getName(), YamlExceptionMapper.class.getName()));
 
         props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERVLET_URIPATH_SUFFIX,
             Optional.ofNullable(restServerParameters.getServletUriPath()).orElse(""));
index 61aeada..42ef1c9 100644 (file)
@@ -3,7 +3,7 @@
  * policy-endpoints
  * ================================================================================
  * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2019-2020,2023 Nordix Foundation.
  * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,13 +66,13 @@ public class JettyJerseyServer extends JettyServletServer {
      * Jersey GSON Classes Init Param Value.
      */
     protected static final String JERSEY_GSON_INIT_CLASSNAMES_PARAM_VALUE =
-                    String.join(",", GsonMessageBodyHandler.class.getName(), JsonExceptionMapper.class.getName());
+        String.join(",", GsonMessageBodyHandler.class.getName(), JsonExceptionMapper.class.getName());
 
     /**
      * Jersey Swagger Classes Init Param Value.
      */
     protected static final String SWAGGER_INIT_CLASSNAMES_PARAM_VALUE =
-            "io.swagger.jaxrs.listing.ApiListingResource," + "io.swagger.jaxrs.listing.SwaggerSerializers";
+        "io.swagger.jaxrs.listing.ApiListingResource," + "io.swagger.jaxrs.listing.SwaggerSerializers";
 
     /**
      * Logger.
@@ -96,14 +96,15 @@ public class JettyJerseyServer extends JettyServletServer {
      * @param https enable https?
      * @param host host server host
      * @param port port server port
+     * @param sniHostCheck SNI Host checking flag
      * @param swagger support swagger?
      * @param contextPath context path
-     *
      * @throws IllegalArgumentException in invalid arguments are provided
      */
-    public JettyJerseyServer(String name, boolean https, String host, int port, String contextPath, boolean swagger) {
+    public JettyJerseyServer(String name, boolean https, String host, int port, boolean sniHostCheck,
+        String contextPath, boolean swagger) {
 
-        super(name, https, host, port, contextPath);
+        super(name, https, host, port, sniHostCheck, contextPath);
         if (swagger) {
             this.swaggerId = "swagger-" + this.port;
             attachSwaggerServlet(https);
@@ -123,7 +124,7 @@ public class JettyJerseyServer extends JettyServletServer {
         }
 
         swaggerServlet.setInitParameter(SWAGGER_API_BASEPATH,
-                ((https) ? "https://" : "http://") + hostname + ":" + this.connector.getPort() + "/");
+            ((https) ? "https://" : "http://") + hostname + ":" + this.connector.getPort() + "/");
         swaggerServlet.setInitParameter(SWAGGER_CONTEXT_ID, swaggerId);
         swaggerServlet.setInitParameter(SWAGGER_SCANNER_ID, swaggerId);
         swaggerServlet.setInitParameter(SWAGGER_PRETTY_PRINT, "true");
@@ -144,7 +145,7 @@ public class JettyJerseyServer extends JettyServletServer {
      */
     protected synchronized ServletHolder getServlet(String servletPath) {
         ServletHolder jerseyServlet =
-                super.getServlet(org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
+            super.getServlet(org.glassfish.jersey.servlet.ServletContainer.class, servletPath);
         jerseyServlet.setInitOrder(0);
         return jerseyServlet;
     }
index c5af20c..2f7bdc7 100644 (file)
@@ -3,7 +3,7 @@
  * ONAP
  * ================================================================================
  * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2019-2020,2023 Nordix Foundation.
  * Modifications Copyright (C) 2020-2021 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -65,9 +65,9 @@ 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.
@@ -94,6 +94,12 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
     @Getter
     protected final int port;
 
+    /**
+     * Should SNI host checking be done.
+     */
+    @Getter
+    protected boolean sniHostCheck;
+
     /**
      * Server auth user name.
      */
@@ -148,11 +154,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
      */
-    protected 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()) {
@@ -177,6 +185,7 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
 
         this.host = srvHost;
         this.port = port;
+        this.sniHostCheck = sniHostCheck;
 
         this.contextPath = ctxtPath;
 
@@ -203,8 +212,8 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
         this.jettyServer.setHandler(context);
     }
 
-    protected 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
@@ -221,7 +230,7 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
         context.addFilter(filterClass, tempFilterPath, EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
     }
 
-    protected ServletHolder getServlet(@NonNull  Class<? extends Servlet> servlet, @NonNull  String servletPath) {
+    protected ServletHolder getServlet(@NonNull Class<? extends Servlet> servlet, @NonNull String servletPath) {
         synchronized (servlets) {
             return servlets.computeIfAbsent(servletPath, key -> context.addServlet(servlet, servletPath));
         }
@@ -239,32 +248,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);
             }
         }
 
-        var 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() {
@@ -300,13 +312,17 @@ public abstract class JettyServletServer implements HttpServletServer, Runnable
 
         final var hashLoginService = new HashLoginService();
         final var userStore = new UserStore();
-        userStore.addUser(user, Credential.getCredential(password), new String[] {"user"});
+        userStore.addUser(user, Credential.getCredential(password), new String[] {
+            "user"
+        });
         hashLoginService.setUserStore(userStore);
         hashLoginService.setName(this.connector.getName() + "-login-service");
 
         var constraint = new Constraint();
         constraint.setName(Constraint.__BASIC_AUTH);
-        constraint.setRoles(new String[] {"user"});
+        constraint.setRoles(new String[] {
+            "user"
+        });
         constraint.setAuthenticate(true);
 
         var constraintMapping = new ConstraintMapping();
index c335247..70ac141 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2020 Nordix Foundation.
+ *  Copyright (C) 2020,2023 Nordix Foundation.
  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -61,13 +61,14 @@ public class JettyStaticResourceServer extends JettyServletServer {
      * @param https enable https?
      * @param host host server host
      * @param port port server port
+     * @param sniHostCheck SNI Host checking flag
      * @param contextPath context path
-     *
      * @throws IllegalArgumentException in invalid arguments are provided
      */
-    public JettyStaticResourceServer(String name, boolean https, String host, int port, String contextPath) {
+    public JettyStaticResourceServer(String name, boolean https, String host, int port, boolean sniHostCheck,
+        String contextPath) {
 
-        super(name, https, host, port, contextPath);
+        super(name, https, host, port, sniHostCheck, contextPath);
     }
 
     /**
index 8e3561b..9ffe5cb 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019,2023 Nordix Foundation.
  *  Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  *  Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
  * ================================================================================
@@ -45,6 +45,7 @@ public class RestServerParameters extends ParameterGroupImpl {
     private String userName;
     private String password;
     private boolean https;
+    private boolean sniHostCHeck;
     private boolean aaf;
     private boolean prometheus;
     private String servletClass;
index 46a6c39..b7f854a 100644 (file)
@@ -3,7 +3,7 @@
  * ONAP
  * ================================================================================
  * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
- * Copyright (C) 2022 Nordix Foundation.
+ * Copyright (C) 2022,2023 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -108,6 +108,7 @@ public final class PolicyEndPointProperties {
 
     public static final String PROPERTY_HTTP_HTTPS_SUFFIX = ".https";
     public static final String PROPERTY_HTTP_SWAGGER_SUFFIX = ".swagger";
+    public static final String PROPERTY_HTTP_SNI_HOST_CHECK_SUFFIX = ".sniHostCheck";
 
     public static final String PROPERTY_HTTP_SERIALIZATION_PROVIDER = ".serialization.provider";
 
index c9908ed..da8ea7a 100644 (file)
@@ -4,6 +4,7 @@
  * ================================================================================
  * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Modifications Copyright 2023 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -120,7 +121,7 @@ public class HttpClientTest {
         /* echo server - https + basic auth */
 
         final HttpServletServer echoServerAuth = HttpServletServerFactoryInstance.getServerFactory()
-                        .build("echo", true, LOCALHOST, 6667, "/", false, true);
+                        .build("echo", true, LOCALHOST, 6667, false, "/", false, true);
         echoServerAuth.setBasicAuthentication("x", "y", null);
         echoServerAuth.addServletPackage("/*", HttpClientTest.class.getPackage().getName());
         echoServerAuth.addFilterClass("/*", TestFilter.class.getName());
index 2d4de82..dcb3906 100644 (file)
@@ -3,7 +3,7 @@
  * ONAP
  * ================================================================================
  * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2020,2023 Nordix Foundation.
  * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -382,6 +382,7 @@ public class HttpServerTest {
         server.addFilterClass("/*", TestFilter.class.getName());
 
         // ensure we can serialize the server
+        new GsonTestUtils().compareGson(server, HttpServerTest.class);
         assertThatCode(() -> new GsonTestUtils().compareGson(server, HttpServerTest.class)).doesNotThrowAnyException();
     }
 
@@ -423,7 +424,7 @@ public class HttpServerTest {
         logger.info("-- testMultipleServers() --");
 
         HttpServletServer server1 = HttpServletServerFactoryInstance.getServerFactory()
-                        .build("echo-1", false, LOCALHOST, port, "/", true, true);
+                        .build("echo-1", false, LOCALHOST, port, false, "/", true, true);
         server1.addServletPackage("/*", this.getClass().getPackage().getName());
         server1.waitedStart(5000);
 
@@ -523,7 +524,7 @@ public class HttpServerTest {
         logger.info("-- testSingleStaticResourceServer() --");
 
         HttpServletServer staticServer = HttpServletServerFactoryInstance.getServerFactory()
-                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, false, "/", true);
         Throwable thrown = catchThrowable(() -> staticServer.addServletResource("/*", null));
         assertThat(thrown).isInstanceOf(IllegalArgumentException.class)
                 .hasMessageContaining("No resourceBase provided");
@@ -560,7 +561,7 @@ public class HttpServerTest {
         logger.info("-- testMultiStaticResourceServer() --");
 
         HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
-                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, false, "/", true);
         staticResourceServer.addServletResource("/root/*",
                 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
         staticResourceServer.addServletResource("/alt-root/*",
@@ -585,7 +586,7 @@ public class HttpServerTest {
         logger.info("-- testMultiTypesServer() --");
 
         HttpServletServer staticResourceServer = HttpServletServerFactoryInstance.getServerFactory()
-                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, "/", true);
+                .buildStaticResourceServer("Static Resources Server", false, LOCALHOST, port, false, "/", true);
         staticResourceServer.addServletResource("/root/*",
                 HttpServerTest.class.getClassLoader().getResource("webapps/root").toExternalForm());
         staticResourceServer.waitedStart(5000);