This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new f6182d9ffae CAMEL-20920: camel-xml-io - Fix updating route that previously failed to load due to an error. f6182d9ffae is described below commit f6182d9ffaef31cc37a1fdcbf98da2c2bcb224a6 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Jun 27 07:10:20 2024 +0200 CAMEL-20920: camel-xml-io - Fix updating route that previously failed to load due to an error. --- .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 64 ++++++++++---------- .../camel/dsl/xml/io/ReloadFailingRouteTest.java | 70 ++++++++++++++++++++++ 2 files changed, 103 insertions(+), 31 deletions(-) diff --git a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java index 56bfbd8577c..c3d54777676 100644 --- a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java +++ b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java @@ -120,41 +120,43 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { @Override public void configure() throws Exception { String resourceLocation = input.getLocation(); - switch (xmlInfo.getRootElementName()) { - case "beans", "blueprint", "camel" -> { - BeansDefinition def = camelAppCache.get(resourceLocation); - if (def != null) { - configureCamel(def); - } else { + try { + switch (xmlInfo.getRootElementName()) { + case "beans", "blueprint", "camel" -> { + BeansDefinition def = camelAppCache.get(resourceLocation); + if (def != null) { + configureCamel(def); + } else { + new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) + .parseBeansDefinition() + .ifPresent(this::configureCamel); + } + } + case "routeTemplate", "routeTemplates" -> new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) - .parseBeansDefinition() - .ifPresent(this::configureCamel); + .parseRouteTemplatesDefinition() + .ifPresent(this::setRouteTemplateCollection); + case "templatedRoutes", "templatedRoute" -> + new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) + .parseTemplatedRoutesDefinition() + .ifPresent(this::setTemplatedRouteCollection); + case "rests", "rest" -> new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) + .parseRestsDefinition() + .ifPresent(this::setRestCollection); + case "routes", "route" -> new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) + .parseRoutesDefinition() + .ifPresent(this::addRoutes); + default -> { } } - case "routeTemplate", "routeTemplates" -> - new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) - .parseRouteTemplatesDefinition() - .ifPresent(this::setRouteTemplateCollection); - case "templatedRoutes", "templatedRoute" -> - new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) - .parseTemplatedRoutesDefinition() - .ifPresent(this::setTemplatedRouteCollection); - case "rests", "rest" -> new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) - .parseRestsDefinition() - .ifPresent(this::setRestCollection); - case "routes", "route" -> new XmlModelParser(resource, xmlInfo.getRootElementNamespace()) - .parseRoutesDefinition() - .ifPresent(this::addRoutes); - default -> { - } + } finally { + // knowing this is the last time an XML may have been parsed, we can clear the cache + // (route may get reloaded later) + resourceCache.remove(resourceLocation); + xmlInfoCache.remove(resourceLocation); + camelAppCache.remove(resourceLocation); + preparseDone.remove(resourceLocation); } - - // knowing this is the last time an XML may have been parsed, we can clear the cache - // (route may get reloaded later) - resourceCache.remove(resourceLocation); - xmlInfoCache.remove(resourceLocation); - camelAppCache.remove(resourceLocation); - preparseDone.remove(resourceLocation); } @Override diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/ReloadFailingRouteTest.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/ReloadFailingRouteTest.java new file mode 100644 index 00000000000..61ad2f7d731 --- /dev/null +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/ReloadFailingRouteTest.java @@ -0,0 +1,70 @@ +/* + * 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.dsl.xml.io; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.spi.Resource; +import org.apache.camel.spi.RoutesLoader; +import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.ResourceHelper; +import org.apache.camel.xml.io.XmlPullParserLocationException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ReloadFailingRouteTest { + + @Test + public void testReload() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.start(); + + String invalidRoute = "<route id=\"test\">\n" + + " <from uri=\"seda:xml\"/>\n" + + " <log message=\"Some valid message\"/>\n" + + "\t<setHeader name=\"SomeHeader\">\n" + + "\t\t<toosimple>XYZ</toosimple>\n" + + "\t</setHeader>\n" + + "</route>"; + + String validRoute = "<route id=\"test\">\n" + + " <from uri=\"seda:xml\"/>\n" + + " <log message=\"Some valid message\"/>\n" + + "\t<setHeader name=\"SomeHeader\">\n" + + "\t\t<simple>XYZ</simple>\n" + + "\t</setHeader>\n" + + "</route>"; + + Resource invalidResource = ResourceHelper.fromString("dummy.xml", invalidRoute); + Resource validResource = ResourceHelper.fromString("dummy.xml", validRoute); + + RoutesLoader loader = PluginHelper.getRoutesLoader(context); + try { + loader.updateRoutes(invalidResource); + Assertions.fail(); + } catch (Exception e) { + // expected + Assertions.assertInstanceOf(XmlPullParserLocationException.class, e); + } + + loader.updateRoutes(validResource); + + Assertions.assertEquals(1, context.getRoutes().size()); + + context.stop(); + } +}