You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/03/29 08:20:39 UTC

[camel] branch master updated: Add support for ssl to platform-http-vertx (#3687)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8109edf  Add support for ssl to platform-http-vertx (#3687)
8109edf is described below

commit 8109edfeb722c19fae7968dd92aaa70484bd5014
Author: Luca Burgazzoli <lb...@users.noreply.github.com>
AuthorDate: Sun Mar 29 10:20:20 2020 +0200

    Add support for ssl to platform-http-vertx (#3687)
    
    * Add support for ssl to platform-http-vertx
    
    * Fix CS
    
    * Fix CS
---
 components/camel-platform-http-vertx/pom.xml       |   5 +
 .../http/vertx/VertxPlatformHttpConsumer.java      |   4 +-
 .../http/vertx/VertxPlatformHttpServer.java        | 118 ++++++++++++++++++++-
 .../VertxPlatformHttpServerConfiguration.java      |   9 ++
 .../http/vertx/VertxPlatformHttpEngineTest.java    | 112 ++++++++++++++++++-
 .../src/test/resources/jsse/service.jks            | Bin 0 -> 1969 bytes
 .../src/test/resources/jsse/truststore.jks         | Bin 0 -> 582 bytes
 .../platform/http/PlatformHttpComponent.java       |  73 +++++++------
 .../platform/http/PlatformHttpEndpoint.java        |  48 ++++++++-
 .../main/java/org/apache/camel/spring/Main.java    |   2 +-
 .../camel/maven/packaging/PrepareCatalogMojo.java  |   2 +-
 11 files changed, 329 insertions(+), 44 deletions(-)

diff --git a/components/camel-platform-http-vertx/pom.xml b/components/camel-platform-http-vertx/pom.xml
index a6e4d1a..f30c231 100644
--- a/components/camel-platform-http-vertx/pom.xml
+++ b/components/camel-platform-http-vertx/pom.xml
@@ -56,6 +56,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-http</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
index fec50be..674aad3 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
@@ -83,8 +83,8 @@ public class VertxPlatformHttpConsumer extends DefaultConsumer {
     }
 
     @Override
-    protected void doStart() throws Exception {
-        super.doStart();
+    protected void doInit() throws Exception {
+        super.doInit();
 
         final PlatformHttpEndpoint endpoint = getEndpoint();
         final String path = endpoint.getPath();
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
index 95102e6..2a9bc9f 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.component.platform.http.vertx;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
 import java.util.Collections;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
@@ -23,16 +26,25 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
+
 import io.vertx.core.Handler;
 import io.vertx.core.Vertx;
 import io.vertx.core.VertxOptions;
 import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.net.KeyCertOptions;
+import io.vertx.core.net.TrustOptions;
 import io.vertx.ext.web.Router;
 import io.vertx.ext.web.RoutingContext;
 import io.vertx.ext.web.handler.BodyHandler;
 import org.apache.camel.CamelContext;
 import org.apache.camel.component.platform.http.PlatformHttpConstants;
 import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.camel.support.service.ServiceSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -149,13 +161,19 @@ final class VertxPlatformHttpServer extends ServiceSupport {
             new VertxPlatformHttp(vertx, subRouter, Collections.singletonList(createBodyHandler()))
         );
 
-        //HttpServerOptions options = new HttpServerOptions();
-        if (configuration.getSslContextParameters() != null) {
-            // TODO: add ssl support
-            throw new UnsupportedOperationException("Not yet implemented");
+        SSLContextParameters sslParameters = configuration.getSslContextParameters();
+        if (sslParameters == null && configuration.isUseGlobalSslContextParameters()) {
+            sslParameters = context.getSSLContextParameters();
+        }
+
+        HttpServerOptions options = new HttpServerOptions();
+        if (sslParameters != null) {
+            options.setSsl(true);
+            options.setKeyCertOptions(createKeyCertOptions(sslParameters));
+            options.setTrustOptions(createTrustOptions(sslParameters));
         }
 
-        server = vertx.createHttpServer();
+        server = vertx.createHttpServer(options);
 
         return CompletableFuture.runAsync(
             () -> {
@@ -243,4 +261,94 @@ final class VertxPlatformHttpServer extends ServiceSupport {
             }
         };
     }
+
+    // *****************************
+    //
+    // SSL
+    //
+    // *****************************
+
+    private KeyCertOptions createKeyCertOptions(SSLContextParameters sslContextParameters) {
+        return new KeyCertOptions() {
+            @Override
+            public KeyManagerFactory getKeyManagerFactory(Vertx vertx) throws Exception {
+                return createKeyManagerFactory(sslContextParameters);
+            }
+
+            @Override
+            public KeyCertOptions clone() {
+                return this;
+            }
+        };
+    }
+
+    private KeyManagerFactory createKeyManagerFactory(SSLContextParameters sslContextParameters) throws GeneralSecurityException, IOException {
+        final KeyManagersParameters keyManagers = sslContextParameters.getKeyManagers();
+        if (keyManagers == null) {
+            return null;
+        }
+
+        String kmfAlgorithm = context.resolvePropertyPlaceholders(keyManagers.getAlgorithm());
+        if (kmfAlgorithm == null) {
+            kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
+        }
+
+        KeyManagerFactory kmf;
+        if (keyManagers.getProvider() == null) {
+            kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
+        } else {
+            kmf = KeyManagerFactory.getInstance(kmfAlgorithm, context.resolvePropertyPlaceholders(keyManagers.getProvider()));
+        }
+
+        char[] kmfPassword = null;
+        if (keyManagers.getKeyPassword() != null) {
+            kmfPassword = context.resolvePropertyPlaceholders(keyManagers.getKeyPassword()).toCharArray();
+        }
+
+        KeyStore ks = keyManagers.getKeyStore() == null ? null : keyManagers.getKeyStore().createKeyStore();
+
+        kmf.init(ks, kmfPassword);
+        return kmf;
+    }
+
+    private TrustOptions createTrustOptions(SSLContextParameters sslContextParameters) {
+        return new TrustOptions() {
+            @Override
+            public TrustOptions clone() {
+                return this;
+            }
+
+            @Override
+            public TrustManagerFactory getTrustManagerFactory(Vertx vertx) throws Exception {
+                return createTrustManagerFactory(sslContextParameters);
+            }
+        };
+    }
+
+    private TrustManagerFactory createTrustManagerFactory(SSLContextParameters sslContextParameters) throws GeneralSecurityException, IOException {
+        final TrustManagersParameters trustManagers = sslContextParameters.getTrustManagers();
+        if (trustManagers == null) {
+            return null;
+        }
+
+        TrustManagerFactory tmf = null;
+
+        if (trustManagers.getKeyStore() != null) {
+            String tmfAlgorithm = context.resolvePropertyPlaceholders(trustManagers.getAlgorithm());
+            if (tmfAlgorithm == null) {
+                tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+            }
+
+            if (trustManagers.getProvider() == null) {
+                tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+            } else {
+                tmf = TrustManagerFactory.getInstance(tmfAlgorithm, context.resolvePropertyPlaceholders(trustManagers.getProvider()));
+            }
+
+            KeyStore ks = trustManagers.getKeyStore() == null ? null : trustManagers.getKeyStore().createKeyStore();
+            tmf.init(ks);
+        }
+
+        return tmf;
+    }
 }
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
index ff9bac7..17e2c79 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
@@ -32,6 +32,7 @@ public class VertxPlatformHttpServerConfiguration {
 
     private BodyHandler bodyHandler = new BodyHandler();
     private SSLContextParameters sslContextParameters;
+    private boolean useGlobalSslContextParameters;
 
     public String getBindHost() {
         return bindHost;
@@ -81,6 +82,14 @@ public class VertxPlatformHttpServerConfiguration {
         this.sslContextParameters = sslContextParameters;
     }
 
+    public boolean isUseGlobalSslContextParameters() {
+        return useGlobalSslContextParameters;
+    }
+
+    public void setUseGlobalSslContextParameters(boolean useGlobalSslContextParameters) {
+        this.useGlobalSslContextParameters = useGlobalSslContextParameters;
+    }
+
     public static class BodyHandler {
         private boolean handleFileUploads = true;
         private String uploadsDirectory = "file-uploads";
diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
index 84fa9a5..74df042 100644
--- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
+++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
@@ -20,7 +20,13 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.KeyStoreParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.SSLContextServerParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
 import org.apache.camel.test.AvailablePortFinder;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import static io.restassured.RestAssured.given;
@@ -28,6 +34,44 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 
 public class VertxPlatformHttpEngineTest {
+    public static SSLContextParameters serverSSLParameters;
+    public static SSLContextParameters clientSSLParameters;
+
+    @BeforeAll
+    public static void setUp() {
+        serverSSLParameters = new SSLContextParameters();
+        clientSSLParameters = new SSLContextParameters();
+
+        KeyStoreParameters keystoreParameters = new KeyStoreParameters();
+        keystoreParameters.setResource("jsse/service.jks");
+        keystoreParameters.setPassword("security");
+
+        KeyManagersParameters serviceSSLKeyManagers = new KeyManagersParameters();
+        serviceSSLKeyManagers.setKeyPassword("security");
+        serviceSSLKeyManagers.setKeyStore(keystoreParameters);
+
+        serverSSLParameters.setKeyManagers(serviceSSLKeyManagers);
+
+        KeyStoreParameters truststoreParameters = new KeyStoreParameters();
+        truststoreParameters.setResource("jsse/truststore.jks");
+        truststoreParameters.setPassword("storepass");
+
+        TrustManagersParameters clientAuthServiceSSLTrustManagers = new TrustManagersParameters();
+        clientAuthServiceSSLTrustManagers.setKeyStore(truststoreParameters);
+        serverSSLParameters.setTrustManagers(clientAuthServiceSSLTrustManagers);
+        SSLContextServerParameters clientAuthSSLContextServerParameters = new SSLContextServerParameters();
+        clientAuthSSLContextServerParameters.setClientAuthentication("REQUIRE");
+        serverSSLParameters.setServerParameters(clientAuthSSLContextServerParameters);
+
+        TrustManagersParameters clientSSLTrustManagers = new TrustManagersParameters();
+        clientSSLTrustManagers.setKeyStore(truststoreParameters);
+        clientSSLParameters.setTrustManagers(clientSSLTrustManagers);
+
+        KeyManagersParameters clientAuthClientSSLKeyManagers = new KeyManagersParameters();
+        clientAuthClientSSLKeyManagers.setKeyPassword("security");
+        clientAuthClientSSLKeyManagers.setKeyStore(keystoreParameters);
+        clientSSLParameters.setKeyManagers(clientAuthClientSSLKeyManagers);
+    }
 
     @Test
     public void testEngine() throws Exception {
@@ -38,7 +82,6 @@ public class VertxPlatformHttpEngineTest {
             VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
             conf.setBindPort(port);
 
-            context.disableJMX();
             context.addService(new VertxPlatformHttpServer(context, conf), true, true);
             context.addRoutes(new RouteBuilder() {
                 @Override
@@ -83,4 +126,71 @@ public class VertxPlatformHttpEngineTest {
             context.stop();
         }
     }
+
+    @Test
+    public void testEngineSSL() throws Exception {
+        VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
+        conf.setSslContextParameters(serverSSLParameters);
+        conf.setBindPort(AvailablePortFinder.getNextAvailable());
+
+        CamelContext context = new DefaultCamelContext();
+
+        try {
+            context.addService(new VertxPlatformHttpServer(context, conf), true, true);
+            context.getRegistry().bind("clientSSLContextParameters", clientSSLParameters);
+
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    fromF("platform-http:/")
+                        .transform().body(String.class, b -> b.toUpperCase());
+                }
+            });
+
+            context.start();
+
+            String result = context.createFluentProducerTemplate()
+                .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", conf.getBindPort())
+                .withBody("test")
+                .request(String.class);
+
+            assertThat(result).isEqualTo("TEST");
+        } finally {
+            context.stop();
+        }
+    }
+
+    @Test
+    public void testEngineGlobalSSL() throws Exception {
+        VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
+        conf.setUseGlobalSslContextParameters(true);
+        conf.setBindPort(AvailablePortFinder.getNextAvailable());
+
+        CamelContext context = new DefaultCamelContext();
+
+        try {
+            context.setSSLContextParameters(serverSSLParameters);
+            context.addService(new VertxPlatformHttpServer(context, conf), true, true);
+            context.getRegistry().bind("clientSSLContextParameters", clientSSLParameters);
+
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    fromF("platform-http:/")
+                        .transform().body(String.class, b -> b.toUpperCase());
+                }
+            });
+
+            context.start();
+
+            String result = context.createFluentProducerTemplate()
+                .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", conf.getBindPort())
+                .withBody("test")
+                .request(String.class);
+
+            assertThat(result).isEqualTo("TEST");
+        } finally {
+            context.stop();
+        }
+    }
 }
diff --git a/components/camel-platform-http-vertx/src/test/resources/jsse/service.jks b/components/camel-platform-http-vertx/src/test/resources/jsse/service.jks
new file mode 100644
index 0000000..52321ad
Binary files /dev/null and b/components/camel-platform-http-vertx/src/test/resources/jsse/service.jks differ
diff --git a/components/camel-platform-http-vertx/src/test/resources/jsse/truststore.jks b/components/camel-platform-http-vertx/src/test/resources/jsse/truststore.jks
new file mode 100644
index 0000000..44d82a85
Binary files /dev/null and b/components/camel-platform-http-vertx/src/test/resources/jsse/truststore.jks differ
diff --git a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
index f2d389d..1426f27 100644
--- a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
+++ b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
@@ -47,16 +47,20 @@ public class PlatformHttpComponent extends DefaultComponent implements RestConsu
     private static final Logger LOGGER = LoggerFactory.getLogger(PlatformHttpComponent.class);
 
     @Metadata(label = "advanced", description = "An HTTP Server engine implementation to serve the requests")
-    private PlatformHttpEngine engine;
+    private volatile PlatformHttpEngine engine;
 
-    private boolean localEngine;
+    private volatile boolean localEngine;
+
+    private final Object lock;
 
     public PlatformHttpComponent() {
-        super();
+        this(null);
     }
 
     public PlatformHttpComponent(CamelContext context) {
         super(context);
+
+        this.lock = new Object();
     }
 
     @Override
@@ -83,38 +87,9 @@ public class PlatformHttpComponent extends DefaultComponent implements RestConsu
     }
 
     @Override
-    protected void doInit() throws Exception {
-        if (engine == null) {
-            LOGGER.debug("Lookup platform http engine from registry");
-
-            engine = getCamelContext().getRegistry()
-                .lookupByNameAndType(PlatformHttpConstants.PLATFORM_HTTP_ENGINE_NAME, PlatformHttpEngine.class);
-
-            if (engine == null) {
-                LOGGER.debug("Lookup platform http engine from factory");
-
-                engine = getCamelContext()
-                    .adapt(ExtendedCamelContext.class)
-                    .getFactoryFinder(FactoryFinder.DEFAULT_PATH)
-                    .newInstance(PlatformHttpConstants.PLATFORM_HTTP_ENGINE_FACTORY, PlatformHttpEngine.class)
-                    .orElseThrow(() -> new IllegalStateException(
-                        "PlatformHttpEngine is neither set on this endpoint neither found in Camel Registry or FactoryFinder.")
-                    );
-
-                localEngine = true;
-            }
-        }
-
-        CamelContextAware.trySetCamelContext(engine, getCamelContext());
-        ServiceHelper.initService(engine);
-
-        super.doInit();
-    }
-
-    @Override
     protected void doStart() throws Exception {
         super.doStart();
-        ServiceHelper.startService(engine);
+        ServiceHelper.startService(getOrCreateEngine());
     }
 
     @Override
@@ -191,4 +166,36 @@ public class PlatformHttpComponent extends DefaultComponent implements RestConsu
 
         return consumer;
     }
+
+    PlatformHttpEngine getOrCreateEngine() {
+        if (engine == null) {
+            synchronized (lock) {
+                if (engine == null) {
+                    LOGGER.debug("Lookup platform http engine from registry");
+
+                    engine = getCamelContext().getRegistry()
+                        .lookupByNameAndType(PlatformHttpConstants.PLATFORM_HTTP_ENGINE_NAME, PlatformHttpEngine.class);
+
+                    if (engine == null) {
+                        LOGGER.debug("Lookup platform http engine from factory");
+
+                        engine = getCamelContext()
+                            .adapt(ExtendedCamelContext.class)
+                            .getFactoryFinder(FactoryFinder.DEFAULT_PATH)
+                            .newInstance(PlatformHttpConstants.PLATFORM_HTTP_ENGINE_FACTORY, PlatformHttpEngine.class)
+                            .orElseThrow(() -> new IllegalStateException(
+                                "PlatformHttpEngine is neither set on this endpoint neither found in Camel Registry or FactoryFinder.")
+                            );
+
+                        localEngine = true;
+                    }
+                }
+            }
+        }
+
+        CamelContextAware.trySetCamelContext(engine, getCamelContext());
+        ServiceHelper.initService(engine);
+
+        return engine;
+    }
 }
diff --git a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java
index 3e2c155..ff46508 100644
--- a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java
+++ b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java
@@ -28,7 +28,9 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
+import org.apache.camel.support.DefaultConsumer;
 import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.support.service.ServiceHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -80,7 +82,45 @@ public class PlatformHttpEndpoint extends DefaultEndpoint implements AsyncEndpoi
 
     @Override
     public Consumer createConsumer(Processor processor) throws Exception {
-        return platformHttpEngine.createConsumer(this, processor);
+        return new DefaultConsumer(this, processor) {
+            private Consumer delegatedConsumer;
+
+            @Override
+            public PlatformHttpEndpoint getEndpoint () {
+                return (PlatformHttpEndpoint) super.getEndpoint();
+            }
+
+            @Override
+            protected void doStart () throws Exception {
+                super.doStart();
+
+                delegatedConsumer = getEndpoint().getOrCreateEngine().createConsumer(getEndpoint(), getProcessor());
+                configureConsumer(delegatedConsumer);
+
+                ServiceHelper.startService(delegatedConsumer);
+            }
+
+            @Override
+            protected void doStop () throws Exception {
+                super.doStop();
+
+                ServiceHelper.stopAndShutdownServices(delegatedConsumer);
+            }
+
+            @Override
+            protected void doResume () throws Exception {
+                ServiceHelper.resumeService(delegatedConsumer);
+
+                super.doResume();
+            }
+
+            @Override
+            protected void doSuspend () throws Exception {
+                ServiceHelper.suspendService(delegatedConsumer);
+
+                super.doSuspend();
+            }
+        };
     }
 
     @Override
@@ -144,4 +184,10 @@ public class PlatformHttpEndpoint extends DefaultEndpoint implements AsyncEndpoi
     public void setProduces(String produces) {
         this.produces = produces;
     }
+
+    PlatformHttpEngine getOrCreateEngine() {
+        return platformHttpEngine != null
+            ? platformHttpEngine
+            : ((PlatformHttpComponent)getComponent()).getOrCreateEngine();
+    }
 }
diff --git a/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java b/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
index 940652a..73d0396 100644
--- a/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
+++ b/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
@@ -29,8 +29,8 @@ import java.util.Set;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.ProducerTemplate;
-import org.apache.camel.main.MainCommandLineSupport;
 import org.apache.camel.VetoCamelContextStartException;
+import org.apache.camel.main.MainCommandLineSupport;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.springframework.context.ApplicationContext;
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 250e909..33f8a28 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -66,7 +66,7 @@ import static org.apache.camel.tooling.util.PackageHelper.loadText;
 @Mojo(name = "prepare-catalog", threadSafe = true)
 public class PrepareCatalogMojo extends AbstractMojo {
 
-    private static final String[] EXCLUDE_DOC_FILES = { "camel-core-xml", "camel-http-common", "camel-http-base", "camel-jetty-common", "camel-debezium-common"};
+    private static final String[] EXCLUDE_DOC_FILES = {"camel-core-xml", "camel-http-common", "camel-http-base", "camel-jetty-common", "camel-debezium-common"};
 
     private static final Pattern LABEL_PATTERN = Pattern.compile("\\\"label\\\":\\s\\\"([\\w,]+)\\\"");