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

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

commit 983a62921d8eae1178225b96b78401629adc469a
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Fri Feb 7 16:14:34 2020 +0100

    Ensure that catalog files are added to the native image #686
---
 .../quarkus/core/deployment/BuildProcessor.java    |   6 +-
 .../core/deployment/NativeImageProcessor.java      |  86 ++++++++++++++++-
 .../org/apache/camel/quarkus/core/CamelConfig.java |  50 ++++++++++
 .../camel/quarkus/core/CamelMainRecorder.java      |   1 -
 .../apache/camel/quarkus/core/CamelRecorder.java   |   6 +-
 .../camel/quarkus/core/CamelRuntimeCatalog.java    |  66 +++++++++++++
 .../camel/quarkus/core/FastCamelContext.java       | 107 ++++++++++++++++++++-
 .../java/org/apache/camel/quarkus/core/Flags.java  |   7 ++
 .../apache/camel/quarkus/core/CamelServlet.java    |  23 +++++
 .../core/src/main/resources/application.properties |   5 +-
 .../org/apache/camel/quarkus/core/CamelTest.java   |   8 ++
 11 files changed, 354 insertions(+), 11 deletions(-)

diff --git 
a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java
 
b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java
index 1f27ff7..2672806 100644
--- 
a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java
+++ 
b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java
@@ -356,7 +356,8 @@ class BuildProcessor {
                 CamelModelJAXBContextFactoryBuildItem contextFactory,
                 CamelRoutesLoaderBuildItems.Xml xmlLoader,
                 CamelFactoryFinderResolverBuildItem 
factoryFinderResolverBuildItem,
-                BeanContainerBuildItem beanContainer) {
+                BeanContainerBuildItem beanContainer,
+                CamelConfig config) {
 
             RuntimeValue<CamelContext> context = recorder.createContext(
                     registry.getRegistry(),
@@ -365,7 +366,8 @@ class BuildProcessor {
                     xmlLoader.getLoader(),
                     factoryFinderResolverBuildItem.getFactoryFinderResolver(),
                     beanContainer.getValue(),
-                    CamelSupport.getCamelVersion());
+                    CamelSupport.getCamelVersion(),
+                    config);
 
             return new CamelContextBuildItem(context);
         }
diff --git 
a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java
 
b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java
index ee075d8..f8f1d04 100644
--- 
a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java
+++ 
b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java
@@ -16,14 +16,20 @@
  */
 package org.apache.camel.quarkus.core.deployment;
 
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import io.quarkus.deployment.ApplicationArchive;
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
 import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import 
io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
 import org.apache.camel.CamelContext;
@@ -33,12 +39,18 @@ import org.apache.camel.Converter;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Producer;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.impl.engine.DefaultComponentResolver;
+import org.apache.camel.impl.engine.DefaultDataFormatResolver;
+import org.apache.camel.impl.engine.DefaultLanguageResolver;
+import org.apache.camel.quarkus.core.CamelConfig;
 import org.apache.camel.quarkus.core.Flags;
+import org.apache.camel.quarkus.core.deployment.util.PathFilter;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.ExchangeFormatter;
 import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.ScheduledPollConsumerScheduler;
 import org.apache.camel.spi.StreamCachingStrategy;
+import org.apache.camel.support.CamelContextHelper;
 import org.jboss.jandex.AnnotationTarget.Kind;
 import org.jboss.jandex.AnnotationValue;
 import org.jboss.jandex.ClassInfo;
@@ -47,7 +59,11 @@ import org.jboss.jandex.IndexView;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.commons.lang3.ClassUtils.getPackageName;
+
 class NativeImageProcessor {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(NativeImageProcessor.class);
+
     /*
      * NativeImage configuration steps related to camel core.
      */
@@ -82,7 +98,6 @@ class NativeImageProcessor {
                     .filter(CamelSupport::isPublic)
                     .forEach(v -> reflectiveClass.produce(new 
ReflectiveClassBuildItem(true, false, v.name().toString())));
 
-            Logger log = LoggerFactory.getLogger(NativeImageProcessor.class);
             DotName converter = 
DotName.createSimple(Converter.class.getName());
             List<ClassInfo> converterClasses = view.getAnnotations(converter)
                     .stream()
@@ -94,20 +109,20 @@ class NativeImageProcessor {
                         // CoreStaticTypeConverterLoader
                         // need to revisit with Camel 3.0.0-M3 which should 
improve this area
                         if 
(ai.target().asClass().name().toString().startsWith("org.apache.camel.converter."))
 {
-                            log.debug("Ignoring core " + ai + " " + 
ai.target().asClass().name());
+                            LOGGER.debug("Ignoring core " + ai + " " + 
ai.target().asClass().name());
                             return false;
                         } else if (isLoader) {
-                            log.debug("Ignoring " + ai + " " + 
ai.target().asClass().name());
+                            LOGGER.debug("Ignoring " + ai + " " + 
ai.target().asClass().name());
                             return false;
                         } else {
-                            log.debug("Accepting " + ai + " " + 
ai.target().asClass().name());
+                            LOGGER.debug("Accepting " + ai + " " + 
ai.target().asClass().name());
                             return true;
                         }
                     })
                     .map(ai -> ai.target().asClass())
                     .collect(Collectors.toList());
 
-            log.debug("Converter classes: " + converterClasses);
+            LOGGER.debug("Converter classes: " + converterClasses);
             converterClasses
                     .forEach(ci -> reflectiveClass.produce(new 
ReflectiveClassBuildItem(false, false, ci.name().toString())));
 
@@ -132,6 +147,67 @@ class NativeImageProcessor {
 
         }
 
+        /*
+         * Add camel catalog files to the native image.
+         */
+        @BuildStep(onlyIf = Flags.RuntimeCatalogEnabled.class)
+        List<NativeImageResourceBuildItem> camelRuntimeCatalog(
+                CamelConfig config,
+                ApplicationArchivesBuildItem archives,
+                List<CamelServicePatternBuildItem> servicePatterns) {
+
+            List<NativeImageResourceBuildItem> resources = new ArrayList<>();
+
+            final PathFilter pathFilter = servicePatterns.stream()
+                    .collect(
+                            PathFilter.Builder::new,
+                            (builder, patterns) -> 
builder.patterns(patterns.isInclude(), patterns.getPatterns()),
+                            PathFilter.Builder::combine)
+                    .build();
+
+            CamelSupport.services(archives, pathFilter)
+                    .filter(service -> service.name != null && service.type != 
null && service.path != null)
+                    .forEach(service -> {
+
+                        String packageName = getPackageName(service.type);
+                        String jsonPath = String.format("%s/%s.json", 
packageName.replace('.', '/'), service.name);
+
+                        if (config.runtimeCatalog.components
+                                && 
service.path.startsWith(DefaultComponentResolver.RESOURCE_PATH)) {
+                            resources.add(new 
NativeImageResourceBuildItem(jsonPath));
+                        }
+                        if (config.runtimeCatalog.dataformats
+                                && 
service.path.startsWith(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH)) {
+                            resources.add(new 
NativeImageResourceBuildItem(jsonPath));
+                        }
+                        if (config.runtimeCatalog.languages
+                                && 
service.path.startsWith(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH)) {
+                            resources.add(new 
NativeImageResourceBuildItem(jsonPath));
+                        }
+                    });
+
+            if (config.runtimeCatalog.models) {
+                for (ApplicationArchive archive : 
archives.getAllApplicationArchives()) {
+                    final Path root = archive.getArchiveRoot();
+                    final Path resourcePath = 
root.resolve(CamelContextHelper.MODEL_DOCUMENTATION_PREFIX);
+
+                    if (!Files.isDirectory(resourcePath)) {
+                        continue;
+                    }
+
+                    List<String> items = CamelSupport.safeWalk(resourcePath)
+                            .filter(Files::isRegularFile)
+                            .map(root::relativize)
+                            .map(Path::toString)
+                            .collect(Collectors.toList());
+
+                    LOGGER.debug("Register catalog json: {}", items);
+                    resources.add(new NativeImageResourceBuildItem(items));
+                }
+            }
+
+            return resources;
+        }
     }
 
     /*
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
index b564d8f..4873c5e 100644
--- 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
@@ -38,6 +38,12 @@ public class CamelConfig {
     @ConfigItem
     public ServiceConfig service;
 
+    /**
+     * Build time configuration options for CamelRuntimeCatalog.
+     */
+    @ConfigItem
+    public RuntimeCatalogConfig runtimeCatalog;
+
     @ConfigGroup
     public static class MainConfig {
         /**
@@ -174,4 +180,48 @@ public class CamelConfig {
         public Optional<List<String>> includePatterns;
     }
 
+    @ConfigGroup
+    public static class RuntimeCatalogConfig {
+        /**
+         * Enable {@link CamelRuntimeCatalog} functionaries.
+         */
+        @ConfigItem(defaultValue = "true")
+        public boolean enabled;
+
+        /**
+         * Used to control the resolution of components catalog info.
+         * <p>
+         * Note that when building native images, this flag determine if the 
json metadata files related to components
+         * discovered at build time have to be included in the final binary.
+         */
+        @ConfigItem(defaultValue = "true")
+        public boolean components;
+
+        /**
+         * Used to control the resolution of languages catalog info.
+         * <p>
+         * Note that when building native images, this flag determine if the 
json metadata files related to languages
+         * discovered at build time have to be included in the final binary.
+         */
+        @ConfigItem(defaultValue = "true")
+        public boolean languages;
+
+        /**
+         * Used to control the resolution of dataformats catalog info.
+         * <p>
+         * Note that when building native images, this flag determine if the 
json metadata files related to dataformats
+         * discovered at build time have to be included in the final binary.
+         */
+        @ConfigItem(defaultValue = "true")
+        public boolean dataformats;
+
+        /**
+         * Used to control the resolution of model catalog info.
+         * <p>
+         * Note that when building native images, this flag determine if the 
json metadata files related to models
+         * has to be included in the final binary.
+         */
+        @ConfigItem(defaultValue = "true")
+        public boolean models;
+    }
 }
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java
index 118d7a0..f023163 100644
--- 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelMainRecorder.java
@@ -37,7 +37,6 @@ public class CamelMainRecorder {
             RuntimeValue<CamelContext> runtime,
             RuntimeValue<RoutesCollector> routesCollector,
             BeanContainer container) {
-
         CamelMain main = new CamelMain();
         main.setRoutesCollector(routesCollector.getValue());
         main.setCamelContext(runtime.getValue());
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java
index 2dbf2ef..db05027 100644
--- 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java
@@ -25,6 +25,7 @@ import 
org.apache.camel.model.validator.PredicateValidatorDefinition;
 import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.reifier.validator.ValidatorReifier;
+import org.apache.camel.runtimecatalog.RuntimeCamelCatalog;
 import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.Registry;
@@ -62,8 +63,11 @@ public class CamelRecorder {
             RuntimeValue<XmlRoutesLoader> xmlLoader,
             RuntimeValue<FactoryFinderResolver> factoryFinderResolver,
             BeanContainer beanContainer,
-            String version) {
+            String version,
+            CamelConfig config) {
+
         FastCamelContext context = new 
FastCamelContext(factoryFinderResolver.getValue(), version);
+        context.setDefaultExtension(RuntimeCamelCatalog.class, () -> new 
CamelRuntimeCatalog(context, config.runtimeCatalog));
         context.setRegistry(registry.getValue());
         context.setTypeConverterRegistry(typeConverterRegistry.getValue());
         context.setLoadTypeConverters(false);
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRuntimeCatalog.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRuntimeCatalog.java
new file mode 100644
index 0000000..2f82322
--- /dev/null
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRuntimeCatalog.java
@@ -0,0 +1,66 @@
+/*
+ * 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.quarkus.core;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.runtimecatalog.impl.DefaultRuntimeCamelCatalog;
+
+public class CamelRuntimeCatalog extends DefaultRuntimeCamelCatalog {
+    private final CamelConfig.RuntimeCatalogConfig config;
+
+    public CamelRuntimeCatalog(CamelContext camelContext, 
CamelConfig.RuntimeCatalogConfig config) {
+        super(camelContext, true);
+
+        this.config = config;
+    }
+
+    @Override
+    public String modelJSonSchema(String name) {
+        if (!config.enabled || !config.models) {
+            return null;
+        }
+
+        return super.modelJSonSchema(name);
+    }
+
+    @Override
+    public String componentJSonSchema(String name) {
+        if (!config.enabled || !config.components) {
+            return null;
+        }
+
+        return super.componentJSonSchema(name);
+    }
+
+    @Override
+    public String dataFormatJSonSchema(String name) {
+        if (!config.enabled || !config.dataformats) {
+            return null;
+        }
+
+        return super.dataFormatJSonSchema(name);
+    }
+
+    @Override
+    public String languageJSonSchema(String name) {
+        if (!config.enabled || !config.languages) {
+            return null;
+        }
+
+        return super.languageJSonSchema(name);
+    }
+}
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
index 24d6a94..1a2640b 100644
--- 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java
@@ -16,11 +16,14 @@
  */
 package org.apache.camel.quarkus.core;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 
 import org.apache.camel.AsyncProcessor;
+import org.apache.camel.CatalogCamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
 import org.apache.camel.PollingConsumer;
@@ -39,6 +42,7 @@ import org.apache.camel.impl.engine.DefaultBeanIntrospection;
 import org.apache.camel.impl.engine.DefaultCamelBeanPostProcessor;
 import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy;
 import org.apache.camel.impl.engine.DefaultClassResolver;
+import org.apache.camel.impl.engine.DefaultComponentResolver;
 import org.apache.camel.impl.engine.DefaultDataFormatResolver;
 import org.apache.camel.impl.engine.DefaultEndpointRegistry;
 import org.apache.camel.impl.engine.DefaultInflightRepository;
@@ -74,6 +78,7 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.CamelContextNameStrategy;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.EndpointRegistry;
 import org.apache.camel.spi.ExecutorServiceManager;
@@ -81,6 +86,7 @@ import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.HeadersMapFactory;
 import org.apache.camel.spi.InflightRepository;
 import org.apache.camel.spi.Injector;
+import org.apache.camel.spi.Language;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.ManagementNameStrategy;
 import org.apache.camel.spi.MessageHistoryFactory;
@@ -102,14 +108,18 @@ import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.UuidGenerator;
 import org.apache.camel.spi.ValidatorRegistry;
+import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.util.IOHelper;
 
-public class FastCamelContext extends AbstractCamelContext {
+public class FastCamelContext extends AbstractCamelContext implements 
CatalogCamelContext {
     private Model model;
     private final String version;
 
     public FastCamelContext(FactoryFinderResolver factoryFinderResolver, 
String version) {
         super(false);
+
         this.version = version;
+
         setFactoryFinderResolver(factoryFinderResolver);
         setTracing(Boolean.FALSE);
         setDebugging(Boolean.FALSE);
@@ -390,4 +400,99 @@ public class FastCamelContext extends AbstractCamelContext 
{
         forceLazyInitialization();
     }
 
+    @Override
+    public String getComponentParameterJsonSchema(String componentName) throws 
IOException {
+        Class<?> clazz;
+
+        Object instance = getRegistry().lookupByNameAndType(componentName, 
Component.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = 
getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH).findClass(componentName).orElse(null);
+            if (clazz == null) {
+                instance = hasComponent(componentName);
+                if (instance != null) {
+                    clazz = instance.getClass();
+                } else {
+                    return null;
+                }
+            }
+        }
+
+        // special for ActiveMQ as it is really just JMS
+        if ("ActiveMQComponent".equals(clazz.getSimpleName())) {
+            return getComponentParameterJsonSchema("jms");
+        } else {
+            return getJsonSchema(clazz.getPackage().getName(), componentName);
+        }
+    }
+
+    @Override
+    public String getDataFormatParameterJsonSchema(String dataFormatName) 
throws IOException {
+        Class<?> clazz;
+
+        Object instance = getRegistry().lookupByNameAndType(dataFormatName, 
DataFormat.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = 
getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH).findClass(dataFormatName).orElse(null);
+            if (clazz == null) {
+                return null;
+            }
+        }
+
+        return getJsonSchema(clazz.getPackage().getName(), dataFormatName);
+    }
+
+    @Override
+    public String getLanguageParameterJsonSchema(String languageName) throws 
IOException {
+        Class<?> clazz;
+
+        Object instance = getRegistry().lookupByNameAndType(languageName, 
Language.class);
+        if (instance != null) {
+            clazz = instance.getClass();
+        } else {
+            clazz = 
getFactoryFinder(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH).findClass(languageName).orElse(null);
+            if (clazz == null) {
+                return null;
+            }
+        }
+
+        return getJsonSchema(clazz.getPackage().getName(), languageName);
+    }
+
+    @Override
+    public String getEipParameterJsonSchema(String eipName) throws IOException 
{
+        // the eip json schema may be in some of the sub-packages so look until
+        // we find it
+        String[] subPackages = new String[] { "", "/config", "/dataformat", 
"/language", "/loadbalancer", "/rest" };
+        for (String sub : subPackages) {
+            String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub 
+ "/" + eipName + ".json";
+            InputStream inputStream = 
getClassResolver().loadResourceAsStream(path);
+            if (inputStream != null) {
+                try {
+                    return IOHelper.loadText(inputStream);
+                } finally {
+                    IOHelper.close(inputStream);
+                }
+            }
+        }
+        return null;
+    }
+
+    private String getJsonSchema(String packageName, String name) throws 
IOException {
+        String path = packageName.replace('.', '/') + "/" + name + ".json";
+        InputStream inputStream = 
getClassResolver().loadResourceAsStream(path);
+
+        if (inputStream != null) {
+            try {
+                log.debug("loading scheme {} ", path);
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
+            }
+        }
+
+        return null;
+    }
 }
diff --git 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java
 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java
index cdbcbe4..fe94b6d 100644
--- 
a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java
+++ 
b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/Flags.java
@@ -41,4 +41,11 @@ public final class Flags {
             return asBoolean("quarkus.camel.main.routes-discovery.enabled", 
true);
         }
     }
+
+    public static final class RuntimeCatalogEnabled implements BooleanSupplier 
{
+        @Override
+        public boolean getAsBoolean() {
+            return asBoolean("quarkus.camel.runtime-catalog.enabled", true);
+        }
+    }
 }
diff --git 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
index 9aa932d..d83da39 100644
--- 
a/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
+++ 
b/integration-tests/core/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.quarkus.core;
 
+import java.io.IOException;
+
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.json.Json;
@@ -29,6 +31,7 @@ import javax.ws.rs.core.MediaType;
 import org.apache.camel.CamelContext;
 import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.component.log.LogComponent;
+import org.apache.camel.runtimecatalog.RuntimeCamelCatalog;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.support.processor.DefaultExchangeFormatter;
 
@@ -95,4 +98,24 @@ public class CamelServlet {
 
         return true;
     }
+
+    @Path("/catalog/{type}/{name}")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public String catalog(@PathParam("type") String type, @PathParam("name") 
String name) throws IOException {
+        final RuntimeCamelCatalog catalog = 
context.getExtension(RuntimeCamelCatalog.class);
+
+        switch (type) {
+        case "component":
+            return catalog.componentJSonSchema(name);
+        case "language":
+            return catalog.languageJSonSchema(name);
+        case "dataformat":
+            return catalog.dataFormatJSonSchema(name);
+        case "model":
+            return catalog.modelJSonSchema(name);
+        default:
+            throw new IllegalArgumentException("Unknown type " + type);
+        }
+    }
 }
diff --git a/integration-tests/core/src/main/resources/application.properties 
b/integration-tests/core/src/main/resources/application.properties
index 4ea45a6..ebdc415 100644
--- a/integration-tests/core/src/main/resources/application.properties
+++ b/integration-tests/core/src/main/resources/application.properties
@@ -18,11 +18,14 @@
 # Quarkus
 #
 quarkus.log.file.enable = false
+quarkus.log.category."org.apache.camel.quarkus.core".level = DEBUG
 
 #
 # Quarkus :: Camel
 #
-quarkus.camel.main.enabled=false
+quarkus.camel.main.enabled = false
+quarkus.camel.runtime-catalog.enabled = true
+quarkus.camel.runtime-catalog.languages = false
 
 #
 # Camel
diff --git 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
index a46c52c..d665f65 100644
--- 
a/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
+++ 
b/integration-tests/core/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.quarkus.core;
 
+import java.io.IOException;
 import java.net.HttpURLConnection;
 
 import io.quarkus.test.junit.QuarkusTest;
@@ -23,6 +24,7 @@ import io.restassured.RestAssured;
 import io.restassured.response.Response;
 import org.junit.jupiter.api.Test;
 
+import static org.hamcrest.Matchers.emptyOrNullString;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.core.IsNot.not;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -56,4 +58,10 @@ public class CamelTest {
         
RestAssured.when().get("/test/language/simple").then().body(is("true"));
         
RestAssured.when().get("/test/language/undefined").then().body(is("false"));
     }
+
+    @Test
+    public void testCatalogComponent() throws IOException {
+        
RestAssured.when().get("/test/catalog/component/timer").then().body(not(emptyOrNullString()));
+        
RestAssured.when().get("/test/catalog/language/simple").then().body(emptyOrNullString());
+    }
 }

Reply via email to