From 477f4062f0c100ad1d5590a1091761a8f8612b2f Mon Sep 17 00:00:00 2001 From: egernug Date: Mon, 9 Jun 2025 16:17:49 +0100 Subject: [PATCH] Change DMI server from Tomcat to Jetty - Excluded Tomcat from Springboot in both dmi-service and dmi-stub-app - Added dependency for spring-boot-starter-jetty - Added JettyConfig to allowAmbiguousPathSeparators Issue-ID: CPS-2846 Change-Id: I202366bb0a24b0d591dbbd84c6ae3f89b062e44f Signed-off-by: egernug --- dmi-service/pom.xml | 10 ++++ .../org/onap/cps/ncmp/dmi/config/JettyConfig.java | 56 +++++++++++++++++++ .../cps/ncmp/dmi/config/JettyConfigSpec.groovy | 64 ++++++++++++++++++++++ dmi-stub/dmi-stub-app/pom.xml | 11 +++- 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 dmi-service/src/main/java/org/onap/cps/ncmp/dmi/config/JettyConfig.java create mode 100644 dmi-service/src/test/groovy/org/onap/cps/ncmp/dmi/config/JettyConfigSpec.groovy diff --git a/dmi-service/pom.xml b/dmi-service/pom.xml index 56ff6546..bc41ca5e 100644 --- a/dmi-service/pom.xml +++ b/dmi-service/pom.xml @@ -187,6 +187,16 @@ org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty org.springframework.boot diff --git a/dmi-service/src/main/java/org/onap/cps/ncmp/dmi/config/JettyConfig.java b/dmi-service/src/main/java/org/onap/cps/ncmp/dmi/config/JettyConfig.java new file mode 100644 index 00000000..1c1b4225 --- /dev/null +++ b/dmi-service/src/main/java/org/onap/cps/ncmp/dmi/config/JettyConfig.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.config; + +import java.util.EnumSet; +import org.eclipse.jetty.http.UriCompliance; +import org.eclipse.jetty.server.ConnectionFactory; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JettyConfig implements WebServerFactoryCustomizer { + + /** + * Customizes the Jetty server factory to allow encoded slashes in URI paths. + * + * @param jettyServletWebServerFactory the Jetty servlet web server factory to customize + */ + @Override + public void customize(final JettyServletWebServerFactory jettyServletWebServerFactory) { + jettyServletWebServerFactory.addServerCustomizers(server -> { + for (final Connector connector : server.getConnectors()) { + for (final ConnectionFactory connectionFactory : connector.getConnectionFactories()) { + if (connectionFactory instanceof HttpConnectionFactory) { + final HttpConfiguration httpConfiguration + = ((HttpConnectionFactory) connectionFactory).getHttpConfiguration(); + httpConfiguration.setUriCompliance(UriCompliance.from(EnumSet.of( + UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR))); + } + } + } + }); + } +} diff --git a/dmi-service/src/test/groovy/org/onap/cps/ncmp/dmi/config/JettyConfigSpec.groovy b/dmi-service/src/test/groovy/org/onap/cps/ncmp/dmi/config/JettyConfigSpec.groovy new file mode 100644 index 00000000..605d4238 --- /dev/null +++ b/dmi-service/src/test/groovy/org/onap/cps/ncmp/dmi/config/JettyConfigSpec.groovy @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.dmi.config + +import org.eclipse.jetty.server.ConnectionFactory +import org.eclipse.jetty.server.Connector +import org.eclipse.jetty.server.HttpConfiguration +import org.eclipse.jetty.server.HttpConnectionFactory +import org.eclipse.jetty.server.Server +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory +import spock.lang.Specification + +class JettyConfigSpec extends Specification{ + + def objectUnderTest = new JettyConfig() + def server = Mock(Server) + def connector = Mock(Connector) + + def 'Enable support for ambiguous path separators in Jetty Http configuration'() { + given: 'a Jetty server factory' + def jettyServletWebServerFactory = new JettyServletWebServerFactory() + and: 'a mocked connection factory (Http or Non-Http)' + def connectionFactory = connectionFactoryType == 'http' ? Mock(HttpConnectionFactory) : Mock(ConnectionFactory) + and: 'optional mock for HttpConfiguration if applicable' + def httpConfig = null + if (connectionFactory instanceof HttpConnectionFactory) { + httpConfig = Mock(HttpConfiguration) + connectionFactory.getHttpConfiguration() >> httpConfig + } + and: 'mocked components return expected values' + connector.getConnectionFactories() >> [connectionFactory] + server.getConnectors() >> [connector] + when: 'JettyConfig customization is triggered on the server factory' + objectUnderTest.customize(jettyServletWebServerFactory) + and: 'a server customizer is extracted from the configured factory' + def serverCustomizer = jettyServletWebServerFactory.serverCustomizers.first() + and: 'the customizer is applied to the mocked Jetty server' + serverCustomizer.customize(server) + then: 'only the HTTP configuration is updated to allow ambiguous path separators' + expectedCalls * httpConfig.setUriCompliance({ it.toString().contains('AMBIGUOUS_PATH_SEPARATOR') }) + where: 'type of connection factories' + scenario | connectionFactoryType || expectedCalls + 'HttpConnectionFactory - should configure UriCompliance' | 'http' || 1 + 'Non-HttpConnectionFactory - should do nothing' | 'non-http' || 0 + } +} diff --git a/dmi-stub/dmi-stub-app/pom.xml b/dmi-stub/dmi-stub-app/pom.xml index 99c26019..ff83c157 100644 --- a/dmi-stub/dmi-stub-app/pom.xml +++ b/dmi-stub/dmi-stub-app/pom.xml @@ -50,7 +50,16 @@ org.slf4j slf4j-api - + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty ch.qos.logback -- 2.16.6