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

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

commit 920210041d8a44e9cebb00842bccebf07192e6e2
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sat Feb 17 10:20:01 2024 +0100

    CAMEL-20421: camel-knative - Only create consumer/producer http factory 
when needed. Make camel-jbang able to detect only when knative consumer is in 
use and startup embedded HTTP server to make it work out of the box.
---
 .../camel/component/knative/KnativeComponent.java  | 88 ++++++++--------------
 .../camel/component/knative/KnativeEndpoint.java   |  5 +-
 .../knative/http/KnativeHttpConsumerFactory.java   |  7 ++
 .../knative/http/KnativeHttpProducerFactory.java   |  7 ++
 .../component/knative/http/KnativeHttpTest.java    | 11 ---
 .../knative/http/KnativeHttpTestSupport.java       | 18 ++---
 .../java/org/apache/camel/main/KameletMain.java    |  2 +-
 .../DependencyDownloaderClassResolver.java         | 25 +++++-
 .../DependencyDownloaderComponentResolver.java     | 39 +---------
 .../camel/main/download/MainHttpServerFactory.java | 64 ++++++++++++++++
 .../main/download/ResourceResolverListener.java    | 29 +++++++
 11 files changed, 173 insertions(+), 122 deletions(-)

diff --git 
a/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
 
b/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
index cc81602bbf6..2b68cd98efb 100644
--- 
a/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
+++ 
b/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
@@ -55,9 +55,6 @@ public class KnativeComponent extends HealthCheckComponent {
     @Metadata
     private KnativeConsumerFactory consumerFactory;
 
-    private boolean managedProducer;
-    private boolean managedConsumer;
-
     public KnativeComponent() {
         this(null);
     }
@@ -135,6 +132,13 @@ public class KnativeComponent extends HealthCheckComponent 
{
         return producerFactory;
     }
 
+    public synchronized KnativeProducerFactory getOrCreateProducerFactory() 
throws Exception {
+        if (producerFactory == null) {
+            producerFactory = setUpProducerFactory();
+        }
+        return producerFactory;
+    }
+
     /**
      * The protocol producer factory.
      */
@@ -146,6 +150,13 @@ public class KnativeComponent extends HealthCheckComponent 
{
         return consumerFactory;
     }
 
+    public synchronized KnativeConsumerFactory getOrCreateConsumerFactory() 
throws Exception {
+        if (consumerFactory == null) {
+            consumerFactory = setUpConsumerFactory();
+        }
+        return consumerFactory;
+    }
+
     /**
      * The protocol consumer factory.
      */
@@ -173,44 +184,19 @@ public class KnativeComponent extends 
HealthCheckComponent {
     @Override
     protected void doInit() throws Exception {
         super.doInit();
-
-        setUpProducerFactory();
-        setUpConsumerFactory();
-
-        if (this.producerFactory != null && managedProducer) {
-            ServiceHelper.initService(this.producerFactory);
-        }
-        if (this.consumerFactory != null && managedConsumer) {
-            ServiceHelper.initService(this.consumerFactory);
-        }
+        ServiceHelper.initService(consumerFactory, producerFactory);
     }
 
     @Override
     protected void doStart() throws Exception {
         super.doStart();
-
-        if (this.producerFactory != null && managedProducer) {
-            ServiceHelper.startService(this.producerFactory);
-        }
-        if (this.consumerFactory != null && managedConsumer) {
-            ServiceHelper.startService(this.consumerFactory);
-        }
-
-        if (this.producerFactory == null && this.consumerFactory == null) {
-            throw new IllegalStateException("No producer or consumer factory 
has been configured");
-        }
+        ServiceHelper.startService(consumerFactory, producerFactory);
     }
 
     @Override
     protected void doStop() throws Exception {
         super.doStop();
-
-        if (this.producerFactory != null && managedProducer) {
-            ServiceHelper.stopService(this.producerFactory);
-        }
-        if (this.consumerFactory != null && managedConsumer) {
-            ServiceHelper.stopService(this.consumerFactory);
-        }
+        ServiceHelper.stopService(consumerFactory, producerFactory);
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -290,58 +276,44 @@ public class KnativeComponent extends 
HealthCheckComponent {
         return conf;
     }
 
-    private void setUpProducerFactory() throws Exception {
+    private KnativeProducerFactory setUpProducerFactory() throws Exception {
         if (producerFactory == null) {
             this.producerFactory = 
CamelContextHelper.lookup(getCamelContext(), protocol.name(), 
KnativeProducerFactory.class);
-
             if (this.producerFactory == null) {
                 this.producerFactory = getCamelContext()
                         .getCamelContextExtension()
                         
.getBootstrapFactoryFinder(Knative.KNATIVE_TRANSPORT_RESOURCE_PATH)
                         .newInstance(protocol.name() + "-producer", 
KnativeProducerFactory.class)
-                        .orElse(null);
-
-                if (this.producerFactory == null) {
-                    return;
-                }
-
+                        .orElseThrow(() -> new IllegalArgumentException(
+                                "Cannot create KnativeProducerFactory. Make 
sure camel-knative-http JAR is on classpath."));
                 if (configuration.getTransportOptions() != null) {
                     setProperties(producerFactory, new 
HashMap<>(configuration.getTransportOptions()));
                 }
-
-                this.managedProducer = true;
-
-                getCamelContext().addService(this.producerFactory);
+                getCamelContext().addService(this.producerFactory, true, true);
             }
-
-            LOGGER.info("Using Knative producer factory: {} for protocol: {}", 
producerFactory, protocol.name());
+            LOGGER.debug("Using Knative producer factory: {} for protocol: 
{}", producerFactory, protocol.name());
         }
+
+        return producerFactory;
     }
 
-    private void setUpConsumerFactory() throws Exception {
+    private KnativeConsumerFactory setUpConsumerFactory() throws Exception {
         if (consumerFactory == null) {
             this.consumerFactory = 
CamelContextHelper.lookup(getCamelContext(), protocol.name(), 
KnativeConsumerFactory.class);
-
             if (this.consumerFactory == null) {
                 this.consumerFactory = getCamelContext()
                         .getCamelContextExtension()
                         
.getBootstrapFactoryFinder(Knative.KNATIVE_TRANSPORT_RESOURCE_PATH)
                         .newInstance(protocol.name() + "-consumer", 
KnativeConsumerFactory.class)
-                        .orElse(null);
-
-                if (this.consumerFactory == null) {
-                    return;
-                }
+                        .orElseThrow(() -> new IllegalArgumentException(
+                                "Cannot create KnativeConsumerFactory. Make 
sure camel-knative-http JAR is on classpath."));
                 if (configuration.getTransportOptions() != null) {
                     setProperties(consumerFactory, new 
HashMap<>(configuration.getTransportOptions()));
                 }
-
-                this.managedConsumer = true;
-
-                getCamelContext().addService(this.consumerFactory);
+                getCamelContext().addService(this.consumerFactory, true, true);
             }
-
-            LOGGER.info("Using Knative consumer factory: {} for protocol: {}", 
consumerFactory, protocol.name());
+            LOGGER.debug("Using Knative consumer factory: {} for protocol: 
{}", consumerFactory, protocol.name());
         }
+        return consumerFactory;
     }
 }
diff --git 
a/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
 
b/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
index 32bbb81aead..b873764fef8 100644
--- 
a/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
+++ 
b/components/camel-knative/camel-knative-component/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
@@ -90,7 +90,8 @@ public class KnativeEndpoint extends DefaultEndpoint {
         final KnativeResource service = 
lookupServiceDefinition(Knative.EndpointKind.sink);
         final Processor ceProcessor = cloudEventProcessor.producer(this, 
service);
         final Producer producer
-                = getComponent().getProducerFactory().createProducer(this, 
createTransportConfiguration(service), service);
+                = 
getComponent().getOrCreateProducerFactory().createProducer(this, 
createTransportConfiguration(service),
+                        service);
 
         PropertyBindingSupport.build()
                 .withCamelContext(getCamelContext())
@@ -121,7 +122,7 @@ public class KnativeEndpoint extends DefaultEndpoint {
                 = 
PluginHelper.getProcessorFactory(camelContext).createProcessor(camelContext, 
"Pipeline",
                         new Object[] { list });
 
-        Consumer consumer = 
getComponent().getConsumerFactory().createConsumer(this,
+        Consumer consumer = 
getComponent().getOrCreateConsumerFactory().createConsumer(this,
                 createTransportConfiguration(service), service, pipeline);
 
         PropertyBindingSupport.build()
diff --git 
a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpConsumerFactory.java
 
b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpConsumerFactory.java
index e751ab3f06a..d7bbdfbc04a 100644
--- 
a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpConsumerFactory.java
+++ 
b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpConsumerFactory.java
@@ -34,6 +34,13 @@ public class KnativeHttpConsumerFactory extends 
ServiceSupport implements CamelC
     private Router router;
     private CamelContext camelContext;
 
+    public KnativeHttpConsumerFactory() {
+    }
+
+    public KnativeHttpConsumerFactory(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
     public Router getRouter() {
         return router;
     }
diff --git 
a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpProducerFactory.java
 
b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpProducerFactory.java
index 7baae79d835..d5cbe2393ef 100644
--- 
a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpProducerFactory.java
+++ 
b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpProducerFactory.java
@@ -35,6 +35,13 @@ public class KnativeHttpProducerFactory extends 
ServiceSupport implements CamelC
     private WebClientOptions vertxHttpClientOptions;
     private CamelContext camelContext;
 
+    public KnativeHttpProducerFactory() {
+    }
+
+    public KnativeHttpProducerFactory(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
     public Vertx getVertx() {
         return vertx;
     }
diff --git 
a/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTest.java
 
b/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTest.java
index 68667d417ae..f13821d2832 100644
--- 
a/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTest.java
+++ 
b/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTest.java
@@ -46,7 +46,6 @@ import org.apache.camel.test.AvailablePortFinder;
 import org.apache.camel.util.ObjectHelper;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
 
@@ -108,16 +107,6 @@ public class KnativeHttpTest {
     //
     // **************************
 
-    @Test
-    void testCreateComponent() {
-        context.start();
-
-        
assertThat(context.getComponent("knative")).isInstanceOfSatisfying(KnativeComponent.class,
 c -> {
-            
assertThat(c.getProducerFactory()).isInstanceOf(KnativeHttpProducerFactory.class);
-            
assertThat(c.getConsumerFactory()).isInstanceOf(KnativeHttpConsumerFactory.class);
-        });
-    }
-
     void doTestKnativeSource(CloudEvent ce, String basePath, String path) 
throws Exception {
         KnativeComponent component = configureKnativeComponent(
                 context,
diff --git 
a/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTestSupport.java
 
b/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTestSupport.java
index b79c05ddb90..c5c8a33c1a0 100644
--- 
a/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTestSupport.java
+++ 
b/components/camel-knative/camel-knative-http/src/test/java/org/apache/camel/component/knative/http/KnativeHttpTestSupport.java
@@ -21,15 +21,10 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.Consumer;
-import org.apache.camel.Endpoint;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
 import org.apache.camel.component.cloudevents.CloudEvent;
 import org.apache.camel.component.knative.KnativeComponent;
 import org.apache.camel.component.knative.spi.KnativeEnvironment;
 import org.apache.camel.component.knative.spi.KnativeResource;
-import org.apache.camel.component.knative.spi.KnativeTransportConfiguration;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.component.platform.http.PlatformHttpConstants;
 import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpEngine;
@@ -61,19 +56,18 @@ public final class KnativeHttpTestSupport {
         KnativeComponent component = context.getComponent("knative", 
KnativeComponent.class);
         component.setCloudEventsSpecVersion(ce.version());
         component.setEnvironment(environment);
-        component.setConsumerFactory(new KnativeHttpConsumerFactory() {
+        component.setConsumerFactory(new KnativeHttpConsumerFactory(context) {
             @Override
-            public Consumer createConsumer(
-                    Endpoint endpoint, KnativeTransportConfiguration config, 
KnativeResource service, Processor processor) {
+            protected void doBuild() throws Exception {
+                super.doBuild();
                 this.setRouter(VertxPlatformHttpRouter.lookup(context));
-                return super.createConsumer(endpoint, config, service, 
processor);
             }
         });
-        component.setProducerFactory(new KnativeHttpProducerFactory() {
+        component.setProducerFactory(new KnativeHttpProducerFactory(context) {
             @Override
-            public Producer createProducer(Endpoint endpoint, 
KnativeTransportConfiguration config, KnativeResource service) {
+            protected void doBuild() throws Exception {
+                super.doBuild();
                 this.setVertx(VertxPlatformHttpRouter.lookup(context).vertx());
-                return super.createProducer(endpoint, config, service);
             }
         });
 
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 53f73531fa2..ffa1d3ffacb 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -548,7 +548,7 @@ public class KameletMain extends MainCommandLineSupport {
                     new DependencyDownloaderStrategy(answer));
 
             // download class-resolver
-            ClassResolver classResolver = new 
DependencyDownloaderClassResolver(answer, knownDeps);
+            ClassResolver classResolver = new 
DependencyDownloaderClassResolver(answer, knownDeps, silent);
             answer.setClassResolver(classResolver);
             // re-create factory finder with download class-resolver
             FactoryFinderResolver ffr = 
PluginHelper.getFactoryFinderResolver(answer);
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
index fa700f58e60..330728cf27c 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
@@ -17,6 +17,8 @@
 package org.apache.camel.main.download;
 
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.impl.engine.DefaultClassResolver;
@@ -25,18 +27,25 @@ import org.apache.camel.util.ObjectHelper;
 
 public final class DependencyDownloaderClassResolver extends 
DefaultClassResolver {
 
+    private final List<ResourceResolverListener> resourceResolverListeners = 
new ArrayList<>();
     private final KnownDependenciesResolver knownDependenciesResolver;
     private final DependencyDownloader downloader;
+    private final boolean silent;
 
     public DependencyDownloaderClassResolver(CamelContext camelContext,
-                                             KnownDependenciesResolver 
knownDependenciesResolver) {
+                                             KnownDependenciesResolver 
knownDependenciesResolver,
+                                             boolean silent) {
         super(camelContext);
         this.downloader = camelContext.hasService(DependencyDownloader.class);
         this.knownDependenciesResolver = knownDependenciesResolver;
+        this.silent = silent;
+        this.resourceResolverListeners.add(new KNativeHttpServerFactory());
     }
 
     @Override
     public InputStream loadResourceAsStream(String uri) {
+        resourceResolverListeners.forEach(l -> l.onLoadResourceAsStream(uri));
+
         InputStream answer = null;
         try {
             answer = super.loadResourceAsStream(uri);
@@ -93,4 +102,18 @@ public final class DependencyDownloaderClassResolver 
extends DefaultClassResolve
         return answer;
     }
 
+    private class KNativeHttpServerFactory implements ResourceResolverListener 
{
+
+        @Override
+        public void onLoadResourceAsStream(String uri) {
+            try {
+                if 
("META-INF/services/org/apache/camel/knative/transport/http-consumer".equals(uri))
 {
+                    MainHttpServerFactory.setupHttpServer(getCamelContext(), 
silent);
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
 }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java
index 8fd9e2536fb..06bc65678ac 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java
@@ -20,17 +20,11 @@ import java.util.List;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
-import org.apache.camel.Service;
 import org.apache.camel.catalog.CamelCatalog;
 import org.apache.camel.catalog.DefaultCamelCatalog;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
-import org.apache.camel.component.platform.http.main.MainHttpServer;
 import org.apache.camel.component.stub.StubComponent;
 import org.apache.camel.impl.engine.DefaultComponentResolver;
-import org.apache.camel.main.HttpServerConfigurationProperties;
-import org.apache.camel.main.MainConstants;
-import org.apache.camel.main.MainHttpServerFactory;
-import org.apache.camel.main.util.CamelJBangSettingsHelper;
 import org.apache.camel.main.util.SuggestSimilarHelper;
 import org.apache.camel.tooling.model.ComponentModel;
 
@@ -75,25 +69,8 @@ public final class DependencyDownloaderComponentResolver 
extends DefaultComponen
             sc.setShadow(true);
             sc.setShadowPattern(stubPattern);
         }
-        if (answer instanceof PlatformHttpComponent || name.equals("knative")) 
{
-            // set up a default http server on configured port if not already 
done
-            MainHttpServer server = 
camelContext.hasService(MainHttpServer.class);
-            if (server == null) {
-                // need to capture that we use a http-server
-                HttpServerConfigurationProperties config = new 
HttpServerConfigurationProperties(null);
-                
CamelJBangSettingsHelper.writeSettingsIfNotExists("camel.jbang.platform-http.port",
-                        String.valueOf(config.getPort()));
-                if (!silent) {
-                    try {
-                        // enable http server if not silent
-                        MainHttpServerFactory factory = 
resolveMainHttpServerFactory(camelContext);
-                        Service httpServer = factory.newHttpServer(config);
-                        camelContext.addService(httpServer, true, true);
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            }
+        if (answer instanceof PlatformHttpComponent) {
+            MainHttpServerFactory.setupHttpServer(camelContext, silent);
         }
         if (answer == null) {
             List<String> suggestion = 
SuggestSimilarHelper.didYouMean(catalog.findComponentNames(), name);
@@ -120,16 +97,4 @@ public final class DependencyDownloaderComponentResolver 
extends DefaultComponen
         return ACCEPTED_STUB_NAMES.contains(name);
     }
 
-    private static MainHttpServerFactory 
resolveMainHttpServerFactory(CamelContext camelContext) throws Exception {
-        // lookup in service registry first
-        MainHttpServerFactory answer = 
camelContext.getRegistry().findSingleByType(MainHttpServerFactory.class);
-        if (answer == null) {
-            answer = 
camelContext.getCamelContextExtension().getBootstrapFactoryFinder()
-                    .newInstance(MainConstants.PLATFORM_HTTP_SERVER, 
MainHttpServerFactory.class)
-                    .orElseThrow(() -> new IllegalArgumentException(
-                            "Cannot find MainHttpServerFactory on classpath. 
Add camel-platform-http-main to classpath."));
-        }
-        return answer;
-    }
-
 }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
new file mode 100644
index 00000000000..8cbba6d1f00
--- /dev/null
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
@@ -0,0 +1,64 @@
+/*
+ * 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.main.download;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Service;
+import org.apache.camel.component.platform.http.main.MainHttpServer;
+import org.apache.camel.main.HttpServerConfigurationProperties;
+import org.apache.camel.main.MainConstants;
+import org.apache.camel.main.util.CamelJBangSettingsHelper;
+
+public class MainHttpServerFactory {
+
+    public static MainHttpServer setupHttpServer(CamelContext camelContext, 
boolean silent) {
+        // set up a default http server on configured port if not already done
+        MainHttpServer server = camelContext.hasService(MainHttpServer.class);
+        if (server == null) {
+            // need to capture that we use a http-server
+            HttpServerConfigurationProperties config = new 
HttpServerConfigurationProperties(null);
+            
CamelJBangSettingsHelper.writeSettingsIfNotExists("camel.jbang.platform-http.port",
+                    String.valueOf(config.getPort()));
+            if (!silent) {
+                try {
+                    // enable http server if not silent
+                    org.apache.camel.main.MainHttpServerFactory factory = 
resolveMainHttpServerFactory(camelContext);
+                    Service httpServer = factory.newHttpServer(config);
+                    camelContext.addService(httpServer, true, true);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return server;
+    }
+
+    private static org.apache.camel.main.MainHttpServerFactory 
resolveMainHttpServerFactory(CamelContext camelContext)
+            throws Exception {
+        // lookup in service registry first
+        org.apache.camel.main.MainHttpServerFactory answer
+                = 
camelContext.getRegistry().findSingleByType(org.apache.camel.main.MainHttpServerFactory.class);
+        if (answer == null) {
+            answer = 
camelContext.getCamelContextExtension().getBootstrapFactoryFinder()
+                    .newInstance(MainConstants.PLATFORM_HTTP_SERVER, 
org.apache.camel.main.MainHttpServerFactory.class)
+                    .orElseThrow(() -> new IllegalArgumentException(
+                            "Cannot find MainHttpServerFactory on classpath. 
Add camel-platform-http-main to classpath."));
+        }
+        return answer;
+    }
+
+}
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ResourceResolverListener.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ResourceResolverListener.java
new file mode 100644
index 00000000000..c75b8fb97ee
--- /dev/null
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/ResourceResolverListener.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.main.download;
+
+/**
+ * Listener when resources are loaded (eg from src/main/resources)
+ */
+@FunctionalInterface
+public interface ResourceResolverListener {
+
+    /**
+     * Invoked when a resource is attempted to be loaded.
+     */
+    void onLoadResourceAsStream(String uri);
+}

Reply via email to