This is an automated email from the ASF dual-hosted git repository.

orpiske pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit dea274f3a9c30bfb66dafc3f6b92f1f7f8972376
Author: Otavio Rodolfo Piske <angusyo...@gmail.com>
AuthorDate: Wed Sep 7 17:38:25 2022 +0200

    CAMEL-18456: created a test infra module for embedded Jetty
---
 test-infra/camel-test-infra-jetty/pom.xml          |  70 ++++++++++++
 .../src/main/resources/META-INF/MANIFEST.MF        |   0
 .../test/infra/jetty/common/JettyProperties.java   |  29 +++++
 .../infra/jetty/services/JettyConfiguration.java   | 117 +++++++++++++++++++
 .../jetty/services/JettyConfigurationBuilder.java  |  75 +++++++++++++
 .../infra/jetty/services/JettyEmbeddedService.java | 124 +++++++++++++++++++++
 .../test/infra/jetty/services/JettyService.java    |  44 ++++++++
 test-infra/pom.xml                                 |   1 +
 8 files changed, 460 insertions(+)

diff --git a/test-infra/camel-test-infra-jetty/pom.xml 
b/test-infra/camel-test-infra-jetty/pom.xml
new file mode 100644
index 00000000000..6ec3bbb5e3b
--- /dev/null
+++ b/test-infra/camel-test-infra-jetty/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+-->
+<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";>
+    <parent>
+        <artifactId>camel-test-infra-parent</artifactId>
+        <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+        <version>3.19.0-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-test-infra-jetty</artifactId>
+    <name>Camel :: Test Infra :: Jetty</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+        </dependency>
+
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <version>${jetty-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty-version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
diff --git 
a/test-infra/camel-test-infra-jetty/src/main/resources/META-INF/MANIFEST.MF 
b/test-infra/camel-test-infra-jetty/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..e69de29bb2d
diff --git 
a/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/common/JettyProperties.java
 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/common/JettyProperties.java
new file mode 100644
index 00000000000..d01b0604022
--- /dev/null
+++ 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/common/JettyProperties.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.camel.test.infra.jetty.common;
+
+public final class JettyProperties {
+    /**
+     * The Jetty server address in the format host:port
+     */
+    public static final String JETTY_ADDRESS = "jetty.address";
+
+    private JettyProperties() {
+
+    }
+}
diff --git 
a/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfiguration.java
 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfiguration.java
new file mode 100644
index 00000000000..22d11728d45
--- /dev/null
+++ 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.camel.test.infra.jetty.services;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.Servlet;
+
+import org.eclipse.jetty.servlet.ServletHolder;
+
+/**
+ * A configuration holder for embedded Jetty instances
+ */
+public class JettyConfiguration {
+    public static final String ROOT_CONTEXT_PATH = "/";
+
+    /**
+     * A configuration holder for Jetty servlet holders
+     * 
+     * @param <T>
+     */
+    public static class ServletConfiguration<T> {
+        public static final String ROOT_PATH_SPEC = "/*";
+
+        private final T servlet;
+        private final String pathSpec;
+
+        public ServletConfiguration(T servlet, String pathSpec) {
+            this.servlet = servlet;
+            this.pathSpec = pathSpec;
+        }
+
+        public T getServlet() {
+            return servlet;
+        }
+
+        public String getPathSpec() {
+            return pathSpec;
+        }
+
+        public ServletHolder buildServletHolder() {
+            if (servlet instanceof ServletHolder) {
+                return (ServletHolder) servlet;
+            }
+
+            ServletHolder servletHolder = new ServletHolder();
+
+            if (servlet instanceof String) {
+                servletHolder.setClassName((String) servlet);
+            } else {
+                if (servlet instanceof Servlet) {
+                    servletHolder.setServlet((Servlet) servlet);
+                } else {
+                    throw new IllegalArgumentException(
+                            "Unknown servlet type: " + (servlet == null ? 
"null" : servlet.getClass()));
+                }
+            }
+
+            return servletHolder;
+        }
+    }
+
+    private int port;
+    private SSLContext sslContext;
+    private List<ServletConfiguration<?>> servletConfigurations = new 
ArrayList<>();
+    private String contextPath;
+
+    public int getPort() {
+        return port;
+    }
+
+    void setPort(int port) {
+        this.port = port;
+    }
+
+    public SSLContext getSslContext() {
+        return sslContext;
+    }
+
+    void setSslContext(SSLContext sslContext) {
+        this.sslContext = sslContext;
+    }
+
+    public String getContextPath() {
+        return contextPath;
+    }
+
+    public void setContextPath(String contextPath) {
+        this.contextPath = contextPath;
+    }
+
+    void addServletConfiguration(ServletConfiguration<?> servletConfiguration) 
{
+        servletConfigurations.add(servletConfiguration);
+    }
+
+    public List<ServletConfiguration<?>> getServletConfigurations() {
+        return Collections.unmodifiableList(servletConfigurations);
+    }
+}
diff --git 
a/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfigurationBuilder.java
 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfigurationBuilder.java
new file mode 100644
index 00000000000..dc70caab7e0
--- /dev/null
+++ 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyConfigurationBuilder.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.camel.test.infra.jetty.services;
+
+import java.util.function.Supplier;
+
+import javax.net.ssl.SSLContext;
+
+/**
+ * This builder can be used to build and configure a configuration holder for 
embedded Jetty instances
+ */
+public final class JettyConfigurationBuilder {
+    private JettyConfiguration jettyConfiguration = new JettyConfiguration();
+
+    private JettyConfigurationBuilder() {
+    }
+
+    public JettyConfigurationBuilder withPort(int port) {
+        jettyConfiguration.setPort(port);
+
+        return this;
+    }
+
+    public JettyConfigurationBuilder withSslContext(SSLContext sslContext) {
+        jettyConfiguration.setSslContext(sslContext);
+
+        return this;
+    }
+
+    public JettyConfigurationBuilder withSslContext(Supplier<SSLContext> 
contextSupplier) {
+        return withSslContext(contextSupplier::get);
+    }
+
+    public JettyConfigurationBuilder 
addServletConfiguration(JettyConfiguration.ServletConfiguration 
servletConfiguration) {
+        jettyConfiguration.addServletConfiguration(servletConfiguration);
+
+        return this;
+    }
+
+    public JettyConfigurationBuilder withContextPath(String contextPath) {
+        jettyConfiguration.setContextPath(contextPath);
+
+        return this;
+    }
+
+    public JettyConfiguration build() {
+        return jettyConfiguration;
+    }
+
+    public static JettyConfigurationBuilder emptyTemplate() {
+        return new JettyConfigurationBuilder();
+    }
+
+    public static JettyConfiguration bare() {
+        // Setups a very basic Jetty server with a randomly allocated port
+        return emptyTemplate()
+                .withPort(0)
+                .build();
+    }
+}
diff --git 
a/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyEmbeddedService.java
 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyEmbeddedService.java
new file mode 100644
index 00000000000..b3b484cd3c9
--- /dev/null
+++ 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyEmbeddedService.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.camel.test.infra.jetty.services;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.camel.test.infra.jetty.common.JettyProperties;
+import org.awaitility.Awaitility;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+/**
+ * An embedded Jetty service that can be used to run servlets for testing 
purposes
+ */
+public class JettyEmbeddedService implements JettyService, BeforeEachCallback, 
AfterEachCallback {
+
+    private final JettyConfiguration jettyConfiguration;
+    private ServerConnector connector;
+    private Server server;
+
+    /**
+     * Builds an instance of the service using the provided configuration
+     * 
+     * @param jettyConfiguration the configuration to use when building the 
service
+     */
+    public JettyEmbeddedService(JettyConfiguration jettyConfiguration) {
+        this.jettyConfiguration = jettyConfiguration;
+    }
+
+    private ServerConnector createConnector(JettyConfiguration 
jettyConfiguration) {
+        ServerConnector connector;
+        SSLContext sslContext = jettyConfiguration.getSslContext();
+        if (sslContext != null) {
+            SslContextFactory sslContextFactory = new 
SslContextFactory.Server();
+            sslContextFactory.setSslContext(sslContext);
+
+            connector = new ServerConnector(server, new 
SslConnectionFactory(sslContextFactory, null));
+        } else {
+            connector = new ServerConnector(server);
+        }
+
+        return connector;
+    }
+
+    @Override
+    public void registerProperties() {
+        System.setProperty(JettyProperties.JETTY_ADDRESS, "localhost:" + 
getPort());
+    }
+
+    @Override
+    public void initialize() {
+        try {
+            server = new Server(jettyConfiguration.getPort());
+
+            connector = createConnector(jettyConfiguration);
+
+            server.addConnector(connector);
+
+            ServletContextHandler contextHandler = new ServletContextHandler();
+            contextHandler.setContextPath(jettyConfiguration.getContextPath());
+            for (JettyConfiguration.ServletConfiguration servletConfiguration 
: jettyConfiguration.getServletConfigurations()) {
+                
contextHandler.addServlet(servletConfiguration.buildServletHolder(), 
servletConfiguration.getPathSpec());
+            }
+            server.setHandler(contextHandler);
+
+            server.start();
+            Awaitility.await().atMost(10, 
TimeUnit.SECONDS).until(server::isStarted);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            server.stop();
+
+            Awaitility.await().atMost(10, 
TimeUnit.SECONDS).until(server::isStopped);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            server.destroy();
+            server = null;
+        }
+    }
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) throws Exception {
+        shutdown();
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception 
{
+        initialize();
+    }
+
+    @Override
+    public int getPort() {
+        return jettyConfiguration.getPort();
+    }
+}
diff --git 
a/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyService.java
 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyService.java
new file mode 100644
index 00000000000..7b7f5776859
--- /dev/null
+++ 
b/test-infra/camel-test-infra-jetty/src/test/java/org/apache/camel/test/infra/jetty/services/JettyService.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.test.infra.jetty.services;
+
+import org.apache.camel.test.infra.common.services.TestService;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+/**
+ * Test infra service for Jetty
+ */
+public interface JettyService extends BeforeAllCallback, AfterAllCallback, 
TestService {
+    @Override
+    default void beforeAll(ExtensionContext extensionContext) throws Exception 
{
+        initialize();
+    }
+
+    @Override
+    default void afterAll(ExtensionContext extensionContext) throws Exception {
+        shutdown();
+    }
+
+    /**
+     * Gets the port used to run the service
+     * 
+     * @return the port number
+     */
+    int getPort();
+}
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index 6c895552797..e5d6d7eb68e 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -74,5 +74,6 @@
         <module>camel-test-infra-openldap</module>
         <module>camel-test-infra-ignite</module>
         <module>camel-test-infra-hashicorp-vault</module>
+        <module>camel-test-infra-jetty</module>
     </modules>
 </project>

Reply via email to