factory-finder: add tests for camel factories discovery and registration
diff --git a/integration-tests/core-main/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java b/integration-tests/core-main/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
index b1081a0..1d13b31 100644
--- a/integration-tests/core-main/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
+++ b/integration-tests/core-main/src/main/java/org/apache/camel/quarkus/core/CamelServlet.java
@@ -41,6 +41,9 @@
 import org.apache.camel.quarkus.core.runtime.support.MyPair;
 import org.apache.camel.reactive.vertx.VertXReactiveExecutor;
 import org.apache.camel.spi.BeanRepository;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.FactoryFinderResolver;
+import org.apache.camel.spi.Language;
 import org.apache.camel.spi.ReactiveExecutor;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.support.DefaultRegistry;
@@ -104,6 +107,8 @@
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public JsonObject describeMain() {
+        final ExtendedCamelContext camelContext = main.getCamelContext().adapt(ExtendedCamelContext.class);
+
         JsonArrayBuilder listeners = Json.createArrayBuilder();
         main.getMainListeners().forEach(listener -> listeners.add(listener.getClass().getName()));
 
@@ -111,7 +116,7 @@
         main.getRoutesBuilders().forEach(builder -> routeBuilders.add(builder.getClass().getName()));
 
         JsonArrayBuilder routes = Json.createArrayBuilder();
-        main.getCamelContext().getRoutes().forEach(route -> routes.add(route.getId()));
+        camelContext.getRoutes().forEach(route -> routes.add(route.getId()));
 
         JsonObjectBuilder collector = Json.createObjectBuilder();
         collector.add("type", main.getRoutesCollector().getClass().getName());
@@ -121,12 +126,38 @@
             collector.add("type-xml", crc.getXmlRoutesLoader().getClass().getName());
         }
 
+        JsonObjectBuilder dataformatsInRegistry = Json.createObjectBuilder();
+        camelContext.getRegistry().findByTypeWithName(DataFormat.class)
+                .forEach((name, value) -> dataformatsInRegistry.add(name, value.getClass().getName()));
+
+        JsonObjectBuilder languagesInRegistry = Json.createObjectBuilder();
+        camelContext.getRegistry().findByTypeWithName(Language.class)
+                .forEach((name, value) -> languagesInRegistry.add(name, value.getClass().getName()));
+
+        JsonObjectBuilder componentsInRegistry = Json.createObjectBuilder();
+        camelContext.getRegistry().findByTypeWithName(Component.class)
+                .forEach((name, value) -> componentsInRegistry.add(name, value.getClass().getName()));
+
+        JsonObjectBuilder factoryClassMap = Json.createObjectBuilder();
+        FactoryFinderResolver factoryFinderResolver = camelContext.getFactoryFinderResolver();
+        if (factoryFinderResolver instanceof FastFactoryFinderResolver) {
+            ((FastFactoryFinderResolver) factoryFinderResolver).getClassMap().forEach((k, v) -> {
+                factoryClassMap.add(k, v.getName());
+            });
+        }
+
         return Json.createObjectBuilder()
                 .add("routes-collector", collector)
                 .add("listeners", listeners)
                 .add("routeBuilders", routeBuilders)
                 .add("routes", routes)
                 .add("autoConfigurationLogSummary", main.getMainConfigurationProperties().isAutoConfigurationLogSummary())
+                .add("registry", Json.createObjectBuilder()
+                        .add("components", componentsInRegistry)
+                        .add("dataformats", dataformatsInRegistry)
+                        .add("languages", languagesInRegistry))
+                .add("factory-finder", Json.createObjectBuilder()
+                        .add("class-map", factoryClassMap))
                 .build();
     }
 
diff --git a/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTest.java b/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
index 8248b1c..38d9ea9 100644
--- a/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
+++ b/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTest.java
@@ -17,6 +17,7 @@
 package org.apache.camel.quarkus.core;
 
 import java.net.HttpURLConnection;
+import java.util.Map;
 
 import javax.ws.rs.core.MediaType;
 
@@ -29,6 +30,10 @@
 import org.apache.camel.reactive.vertx.VertXReactiveExecutor;
 import org.junit.jupiter.api.Test;
 
+import static org.apache.camel.quarkus.core.CamelTestConditions.doesNotStartWith;
+import static org.apache.camel.quarkus.core.CamelTestConditions.entry;
+import static org.apache.camel.quarkus.core.CamelTestConditions.startsWith;
+import static org.apache.camel.util.CollectionHelper.mapOf;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -86,6 +91,39 @@
                 .doesNotContain("filtered");
 
         assertThat(p.getBoolean("autoConfigurationLogSummary")).isFalse();
+
+        assertThat(p.getMap("registry.components", String.class, String.class)).isNotEmpty();
+        assertThat(p.getMap("registry.dataformats", String.class, String.class)).isEmpty();
+        assertThat(p.getMap("registry.languages", String.class, String.class)).containsExactlyInAnyOrderEntriesOf(mapOf(
+                "header", "org.apache.camel.language.header.HeaderLanguage",
+                "ref", "org.apache.camel.language.ref.RefLanguage",
+                "simple", "org.apache.camel.language.simple.SimpleLanguage",
+                "file", "org.apache.camel.language.simple.FileLanguage"));
+
+        Map<String, String> factoryFinderMap = p.getMap("factory-finder.class-map", String.class, String.class);
+
+        // dataformats
+        assertThat(factoryFinderMap)
+                .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/dataformat/"))
+                .hasEntrySatisfying(entry(
+                        "META-INF/services/org/apache/camel/dataformat/my-dataformat",
+                        "org.apache.camel.quarkus.core.runtime.support.MyDataFormat"));
+
+        // languages
+        assertThat(factoryFinderMap)
+                .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/language/"))
+                .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/simple"))
+                .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/file"))
+                .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/ref"))
+                .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/header"));
+
+        // components
+        assertThat(factoryFinderMap)
+                .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/component/"));
+
+        // misc
+        assertThat(factoryFinderMap)
+                .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/configurer/"));
     }
 
     @Test
diff --git a/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTestConditions.java b/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTestConditions.java
new file mode 100644
index 0000000..fbc813f
--- /dev/null
+++ b/integration-tests/core-main/src/test/java/org/apache/camel/quarkus/core/CamelTestConditions.java
@@ -0,0 +1,54 @@
+/*
+ * 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 java.util.Map;
+import java.util.Objects;
+
+import org.assertj.core.api.Condition;
+
+public final class CamelTestConditions {
+    private CamelTestConditions() {
+    }
+
+    public static Condition<Map.Entry<String, String>> entry(String key, String value) {
+        return new Condition<Map.Entry<String, String>>() {
+            @Override
+            public boolean matches(Map.Entry<String, String> entry) {
+                return Objects.equals(entry.getKey(), key) && Objects.equals(entry.getValue(), value);
+            }
+        };
+    }
+
+    public static Condition<String> startsWith(String prefix) {
+        return new Condition<String>("Starts with " + prefix) {
+            @Override
+            public boolean matches(String value) {
+                return value.startsWith(prefix);
+            }
+        };
+    }
+
+    public static Condition<String> doesNotStartWith(String prefix) {
+        return new Condition<String>("Does not start with " + prefix) {
+            @Override
+            public boolean matches(String value) {
+                return !value.startsWith(prefix);
+            }
+        };
+    }
+}
diff --git a/integration-tests/support/core-main/runtime/pom.xml b/integration-tests/support/core-main/runtime/pom.xml
index a0af6aa..97f5214 100644
--- a/integration-tests/support/core-main/runtime/pom.xml
+++ b/integration-tests/support/core-main/runtime/pom.xml
@@ -51,6 +51,18 @@
     <build>
         <plugins>
             <plugin>
+                <groupId>org.jboss.jandex</groupId>
+                <artifactId>jandex-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>make-index</id>
+                        <goals>
+                            <goal>jandex</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
                 <groupId>io.quarkus</groupId>
                 <artifactId>quarkus-bootstrap-maven-plugin</artifactId>
             </plugin>
diff --git a/integration-tests/support/core-main/runtime/src/main/java/org/apache/camel/quarkus/core/runtime/support/MyDataFormat.java b/integration-tests/support/core-main/runtime/src/main/java/org/apache/camel/quarkus/core/runtime/support/MyDataFormat.java
new file mode 100644
index 0000000..7aec967
--- /dev/null
+++ b/integration-tests/support/core-main/runtime/src/main/java/org/apache/camel/quarkus/core/runtime/support/MyDataFormat.java
@@ -0,0 +1,42 @@
+/*
+ * 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.runtime.support;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+
+public class MyDataFormat implements DataFormat {
+    @Override
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
+        return null;
+    }
+
+    @Override
+    public void start() {
+    }
+
+    @Override
+    public void stop() {
+    }
+}
diff --git a/integration-tests/support/core-main/runtime/src/main/resources/META-INF/services/org/apache/camel/dataformat/my-dataformat b/integration-tests/support/core-main/runtime/src/main/resources/META-INF/services/org/apache/camel/dataformat/my-dataformat
new file mode 100644
index 0000000..8d16b99
--- /dev/null
+++ b/integration-tests/support/core-main/runtime/src/main/resources/META-INF/services/org/apache/camel/dataformat/my-dataformat
@@ -0,0 +1,18 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+class = org.apache.camel.quarkus.core.runtime.support.MyDataFormat
\ No newline at end of file