Merge pull request #581 from lburgazzoli/github-543

Add tests for #543
diff --git a/extensions/core-xml/deployment/pom.xml b/extensions/core-xml/deployment/pom.xml
index c49ad79..c398dd9 100644
--- a/extensions/core-xml/deployment/pom.xml
+++ b/extensions/core-xml/deployment/pom.xml
@@ -58,6 +58,52 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-jaxb-deployment</artifactId>
         </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-direct</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-deployment</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy-jsonb-deployment</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-junit5-internal</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.rest-assured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.hamcrest</groupId>
+                    <artifactId>hamcrest-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java
new file mode 100644
index 0000000..abf5333
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelDevModeTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.xml.deployment;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.QuarkusDevModeTest;
+import io.restassured.RestAssured;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.awaitility.Awaitility.await;
+
+public class CamelDevModeTest {
+    static Path BASE;
+
+    @RegisterExtension
+    static final QuarkusDevModeTest TEST = new QuarkusDevModeTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
+                    .addClass(CamelSupportServlet.class)
+                    .addAsResource(applicationProperties(), "application.properties"));
+
+    @BeforeAll
+    public static void setUp() {
+        try {
+            BASE = Files.createTempDirectory("camel-devmode-");
+            copy("routes.1", "routes.xml");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @AfterAll
+    public static void cleanUp() throws IOException {
+        Files.walk(BASE)
+                .sorted(Comparator.reverseOrder())
+                .map(Path::toFile)
+                .forEach(File::delete);
+    }
+
+    public static Asset applicationProperties() {
+        Writer writer = new StringWriter();
+
+        Properties props = new Properties();
+        props.setProperty("camel.main.xml-routes", "file:" + BASE.toAbsolutePath().toString() + "/routes.xml");
+
+        try {
+            props.store(writer, "");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return new StringAsset(writer.toString());
+    }
+
+    public static void copy(String source, String target) throws IOException {
+        Files.copy(
+                CamelDevModeTest.class.getResourceAsStream("/" + source),
+                BASE.resolve(target),
+                StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    public static List<String> routes() {
+        return RestAssured.when()
+                .get("/test/describe")
+                .then()
+                .statusCode(200)
+                .extract()
+                .body()
+                .jsonPath().getList("routes", String.class);
+    }
+
+    @Test
+    public void testRoutesDiscovery() throws IOException {
+        await().atMost(10, TimeUnit.SECONDS).until(() -> {
+            List<String> routes = routes();
+            return routes.size() == 1 && routes.contains("r1");
+        });
+
+        copy("routes.2", "routes.xml");
+
+        await().atMost(10, TimeUnit.SECONDS).until(() -> {
+            List<String> routes = routes();
+            return routes.size() == 1 && routes.contains("r2");
+        });
+    }
+}
diff --git a/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java
new file mode 100644
index 0000000..92aac18
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/java/org/apache/camel/quarkus/component/xml/deployment/CamelSupportServlet.java
@@ -0,0 +1,48 @@
+/*
+ * 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.component.xml.deployment;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.CamelContext;
+
+@Path("/test")
+@ApplicationScoped
+public class CamelSupportServlet {
+    @Inject
+    CamelContext context;
+
+    @Path("/describe")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public JsonObject describeMain() {
+        JsonArrayBuilder routes = Json.createArrayBuilder();
+        context.getRoutes().forEach(route -> routes.add(route.getId()));
+
+        return Json.createObjectBuilder()
+                .add("routes", routes)
+                .build();
+    }
+}
diff --git a/extensions/core-xml/deployment/src/test/resources/routes.1 b/extensions/core-xml/deployment/src/test/resources/routes.1
new file mode 100644
index 0000000..9150f91
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/resources/routes.1
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://camel.apache.org/schema/spring"
+        xsi:schemaLocation="
+            http://camel.apache.org/schema/spring
+            http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+    <route id="r1">
+        <from uri="direct:start"/>
+        <to uri="direct:end"/>
+    </route>
+
+</routes>
\ No newline at end of file
diff --git a/extensions/core-xml/deployment/src/test/resources/routes.2 b/extensions/core-xml/deployment/src/test/resources/routes.2
new file mode 100644
index 0000000..1e177f2
--- /dev/null
+++ b/extensions/core-xml/deployment/src/test/resources/routes.2
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="http://camel.apache.org/schema/spring"
+        xsi:schemaLocation="
+            http://camel.apache.org/schema/spring
+            http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+    <route id="r2">
+        <from uri="direct:start"/>
+        <to uri="direct:end"/>
+    </route>
+
+</routes>
\ No newline at end of file
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 fa2a9de..e864c84 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
@@ -24,6 +24,7 @@
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
+import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
@@ -177,7 +178,14 @@
         // languages are automatically discovered by build steps so we can reduce the
         // operations done by the standard resolver by looking them up directly from the
         // registry
-        return (name, context) -> context.getRegistry().lookupByNameAndType(name, Language.class);
+        return (name, context) -> {
+            Language answer = context.getRegistry().lookupByNameAndType(name, Language.class);
+            if (answer == null) {
+                throw new NoSuchLanguageException(name);
+            }
+
+            return answer;
+        };
     }
 
     @Override
diff --git a/extensions/dozer/deployment/src/main/java/org/apache/camel/quarkus/component/dozer/deployment/DozerProcessor.java b/extensions/dozer/deployment/src/main/java/org/apache/camel/quarkus/component/dozer/deployment/DozerProcessor.java
index eeb48c1..a106b61 100644
--- a/extensions/dozer/deployment/src/main/java/org/apache/camel/quarkus/component/dozer/deployment/DozerProcessor.java
+++ b/extensions/dozer/deployment/src/main/java/org/apache/camel/quarkus/component/dozer/deployment/DozerProcessor.java
@@ -23,6 +23,7 @@
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.jaxb.deployment.JaxbFileRootBuildItem;
 
 import java.io.File;
 import java.math.BigDecimal;
@@ -38,22 +39,6 @@
 
 import com.github.dozermapper.core.DozerBeanMapperBuilder;
 import com.github.dozermapper.core.Mapper;
-import com.github.dozermapper.core.builder.model.jaxb.AllowedExceptionsDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.ClassDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.ConfigurationDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.ConverterTypeDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.CopyByReferencesDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.CustomConvertersDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.FieldDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.FieldDefinitionDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.FieldExcludeDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.FieldType;
-import com.github.dozermapper.core.builder.model.jaxb.MappingDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.MappingsDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.Relationship;
-import com.github.dozermapper.core.builder.model.jaxb.Type;
-import com.github.dozermapper.core.builder.model.jaxb.VariableDefinition;
-import com.github.dozermapper.core.builder.model.jaxb.VariablesDefinition;
 import com.sun.el.ExpressionFactoryImpl;
 
 import org.apache.camel.component.dozer.DozerConfiguration;
@@ -74,6 +59,11 @@
     }
 
     @BuildStep
+    JaxbFileRootBuildItem dozerJaxbFileRoot() {
+        return new JaxbFileRootBuildItem("com/github/dozermapper/core/builder/model/jaxb");
+    }
+
+    @BuildStep(applicationArchiveMarkers = { "com/github/dozermapper/core" })
     void configureCamelDozer(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
             BuildProducer<NativeImageResourceBuildItem> nativeImage,
             CamelDozerConfig camelDozerConfig) {
@@ -87,15 +77,14 @@
                 .map(uri -> new NativeImageResourceBuildItem(uri.getPath()))
                 .forEach(nativeImage::produce);
 
-        // Add Dozer JAXB resources to the image
+        // Add Dozer DTD & XSD resources to the image
         nativeImage.produce(new NativeImageResourceBuildItem(
                 "dtd/bean-mapping.dtd",
                 "dtd/bean-mapping-6.0.0.dtd",
                 "dtd/bean-mapping-6.2.0.dtd",
                 "schema/bean-mapping.xsd",
                 "schema/bean-mapping-6.0.0.xsd",
-                "schema/bean-mapping-6.2.0.xsd",
-                "com/github/dozermapper/core/builder/model/jaxb/jaxb.index"));
+                "schema/bean-mapping-6.2.0.xsd"));
 
         reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
                 BigDecimal[].class,
@@ -123,29 +112,10 @@
 
         reflectiveClass.produce(
                 new ReflectiveClassBuildItem(false, false,
-                        "com.github.dozermapper.core.builder.model.jaxb.package-info",
                         "com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl"));
 
         reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, DozerConfiguration.class));
 
-        reflectiveClass.produce(new ReflectiveClassBuildItem(true, true,
-                AllowedExceptionsDefinition.class,
-                ClassDefinition.class,
-                ConfigurationDefinition.class,
-                ConverterTypeDefinition.class,
-                CopyByReferencesDefinition.class,
-                CustomConvertersDefinition.class,
-                FieldDefinition.class,
-                FieldDefinitionDefinition.class,
-                FieldExcludeDefinition.class,
-                FieldType.class,
-                MappingDefinition.class,
-                MappingsDefinition.class,
-                Relationship.class,
-                Type.class,
-                VariableDefinition.class,
-                VariablesDefinition.class));
-
         if (camelDozerConfig.mappingFiles.isPresent()) {
             // Register for reflection any classes participating in Dozer mapping
             Mapper mapper = DozerBeanMapperBuilder.create()
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 25e64fd..9aa932d 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,18 +16,18 @@
  */
 package org.apache.camel.quarkus.core;
 
-import java.util.Set;
-
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.json.Json;
 import javax.json.JsonObject;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 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.spi.Registry;
 import org.apache.camel.support.processor.DefaultExchangeFormatter;
@@ -37,6 +37,8 @@
 public class CamelServlet {
     @Inject
     Registry registry;
+    @Inject
+    CamelContext context;
 
     @Path("/registry/log/exchange-formatter")
     @GET
@@ -78,7 +80,19 @@
     @GET
     @Produces(MediaType.TEXT_PLAIN)
     public String contextVersion() {
-        Set<CamelContext> camelContexts = registry.findByType(CamelContext.class);
-        return camelContexts.isEmpty() ? "" : camelContexts.iterator().next().getVersion();
+        return context.getVersion();
+    }
+
+    @Path("/language/{name}")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public boolean resolveLanguage(@PathParam("name") String name) {
+        try {
+            context.resolveLanguage(name);
+        } catch (NoSuchLanguageException e) {
+            return false;
+        }
+
+        return true;
     }
 }
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 e5a9abd..a46c52c 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
@@ -50,4 +50,10 @@
     public void testCamelContextVersion() {
         RestAssured.when().get("/test/context/version").then().body(not(""));
     }
+
+    @Test
+    public void testResolveLanguages() {
+        RestAssured.when().get("/test/language/simple").then().body(is("true"));
+        RestAssured.when().get("/test/language/undefined").then().body(is("false"));
+    }
 }
diff --git a/pom.xml b/pom.xml
index a7e6ba7..e847141 100644
--- a/pom.xml
+++ b/pom.xml
@@ -301,6 +301,8 @@
                             <exclude>ide-config/**</exclude>
                             <exclude>mvnw*</exclude>
                             <exclude>node/**</exclude>
+                            <exclude>**/resources/routes.1</exclude>
+                            <exclude>**/resources/routes.2</exclude>
                         </excludes>
                         <mapping>
                             <groovy>SLASHSTAR_STYLE</groovy>