Repository: camel Updated Branches: refs/heads/master df701cc37 -> 6ad29b2ec
Add capability to load REST DSL from XML files. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/976ae698 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/976ae698 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/976ae698 Branch: refs/heads/master Commit: 976ae698c920eb33c32f7d61844c3d0817ea2bff Parents: df701cc Author: Askannon <askan...@flexarc.com> Authored: Tue Jan 5 13:32:43 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Jan 5 17:40:44 2016 +0100 ---------------------------------------------------------------------- .../java/org/apache/camel/CamelContext.java | 10 ++ .../apache/camel/impl/DefaultCamelContext.java | 30 ++++++ .../apache/camel/model/ModelCamelContext.java | 10 ++ ...melContextAddRestDefinitionsFromXmlTest.java | 102 +++++++++++++++++++ .../apache/camel/model/LoadRestFromXmlTest.java | 87 ++++++++++++++++ .../resources/org/apache/camel/impl/rest1.xml | 20 ++++ .../org/apache/camel/model/barRest.xml | 22 ++++ 7 files changed, 281 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/main/java/org/apache/camel/CamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java b/camel-core/src/main/java/org/apache/camel/CamelContext.java index cb21071..727a2b7 100644 --- a/camel-core/src/main/java/org/apache/camel/CamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java @@ -34,6 +34,7 @@ import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RoutesDefinition; import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.rest.RestsDefinition; import org.apache.camel.spi.AsyncProcessorAwaitManager; import org.apache.camel.spi.CamelContextNameStrategy; import org.apache.camel.spi.ClassResolver; @@ -627,6 +628,15 @@ public interface CamelContext extends SuspendableService, RuntimeConfiguration { RoutesDefinition loadRoutesDefinition(InputStream is) throws Exception; /** + * Loads a collection of rest definitions from the given {@link java.io.InputStream}. + * + * @param is input stream with the rest(s) definition to add + * @throws Exception if the rest definitions could not be loaded for whatever reason + * @return the rest definitions + */ + RestsDefinition loadRestsDefinition(InputStream is) throws Exception; + + /** * Adds a collection of route definitions to the context * * @param routeDefinitions the route(s) definition to add http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java index 507187c..cef6b6a 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java @@ -97,6 +97,7 @@ import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RouteDefinitionHelper; import org.apache.camel.model.RoutesDefinition; import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.rest.RestsDefinition; import org.apache.camel.processor.interceptor.BacklogDebugger; import org.apache.camel.processor.interceptor.BacklogTracer; import org.apache.camel.processor.interceptor.Debug; @@ -868,6 +869,35 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon return answer; } + public synchronized RestsDefinition loadRestsDefinition(InputStream is) throws Exception { + // load routes using JAXB + if (jaxbContext == null) { + // must use classloader from CamelContext to have JAXB working + jaxbContext = getModelJAXBContextFactory().newJAXBContext(); + } + + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + Object result = unmarshaller.unmarshal(is); + + if (result == null) { + throw new IOException("Cannot unmarshal to rests using JAXB from input stream: " + is); + } + + // can either be routes or a single route + RestsDefinition answer; + if (result instanceof RestDefinition) { + RestDefinition rest = (RestDefinition) result; + answer = new RestsDefinition(); + answer.getRests().add(rest); + } else if (result instanceof RestsDefinition) { + answer = (RestsDefinition) result; + } else { + throw new IllegalArgumentException("Unmarshalled object is an unsupported type: " + ObjectHelper.className(result) + " -> " + result); + } + + return answer; + } + public synchronized void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { if (routeDefinitions == null || routeDefinitions.isEmpty()) { return; http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/main/java/org/apache/camel/model/ModelCamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/ModelCamelContext.java b/camel-core/src/main/java/org/apache/camel/model/ModelCamelContext.java index 912aa62..e2fa327 100644 --- a/camel-core/src/main/java/org/apache/camel/model/ModelCamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/model/ModelCamelContext.java @@ -23,6 +23,7 @@ import java.util.Map; import org.apache.camel.CamelContext; import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.rest.RestsDefinition; /** * Model level interface for the {@link CamelContext} @@ -54,6 +55,15 @@ public interface ModelCamelContext extends CamelContext { RoutesDefinition loadRoutesDefinition(InputStream is) throws Exception; /** + * Loads a collection of rest definitions from the given {@link java.io.InputStream}. + * + * @param is input stream with the rest(s) definition to add + * @throws Exception if the rest definitions could not be loaded for whatever reason + * @return the rest definitions + */ + RestsDefinition loadRestsDefinition(InputStream is) throws Exception; + + /** * Adds a collection of route definitions to the context * <p/> * <b>Important: </b> Each route in the same {@link org.apache.camel.CamelContext} must have an <b>unique</b> route id. http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRestDefinitionsFromXmlTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRestDefinitionsFromXmlTest.java b/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRestDefinitionsFromXmlTest.java new file mode 100644 index 0000000..2a6025b --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRestDefinitionsFromXmlTest.java @@ -0,0 +1,102 @@ +/** + * 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.impl; + +import java.net.URL; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.rest.DummyRestConsumerFactory; +import org.apache.camel.component.rest.DummyRestProcessorFactory; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.model.rest.RestDefinition; + +/** + * @version + */ +public class CamelContextAddRestDefinitionsFromXmlTest extends ContextTestSupport { + + protected JAXBContext jaxbContext; + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("dummy-rest", new DummyRestConsumerFactory()); + jndi.bind("dummy-rest-api", new DummyRestProcessorFactory()); + return jndi; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + jaxbContext = context.getModelJAXBContextFactory().newJAXBContext(); + } + + protected Object parseUri(String uri) throws JAXBException { + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + URL resource = getClass().getResource(uri); + assertNotNull("Cannot find resource on the classpath: " + uri, resource); + Object value = unmarshaller.unmarshal(resource); + return value; + } + + protected RestDefinition loadRest(String uri) throws Exception { + Object rest = parseUri(uri); + return assertIsInstanceOf(RestDefinition.class, rest); + } + + public void testAddRestDefinitionsFromXml() throws Exception { + RestDefinition rest = loadRest("rest1.xml"); + assertNotNull(rest); + + assertEquals("foo", rest.getId()); + assertEquals(0, context.getRestDefinitions().size()); + + context.getRestDefinitions().add(rest); + assertEquals(1, context.getRestDefinitions().size()); + + final List<RouteDefinition> routeDefinitions = rest.asRouteDefinition(context); + + for (final RouteDefinition routeDefinition : routeDefinitions) { + context.addRouteDefinition(routeDefinition); + } + + assertEquals(2, context.getRoutes().size()); + + assertTrue("Route should be started", context.getRouteStatus("route1").isStarted()); + + getMockEndpoint("mock:bar").expectedBodiesReceived("Hello World"); + template.sendBody("seda:get-say-hello-bar", "Hello World"); + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + restConfiguration().host("localhost").component("dummy-rest").apiContextPath("/api-docs"); + } + }; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/test/java/org/apache/camel/model/LoadRestFromXmlTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/model/LoadRestFromXmlTest.java b/camel-core/src/test/java/org/apache/camel/model/LoadRestFromXmlTest.java new file mode 100644 index 0000000..5258ea0 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/model/LoadRestFromXmlTest.java @@ -0,0 +1,87 @@ +/** + * 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.model; + +import java.io.InputStream; +import java.util.List; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.rest.DummyRestConsumerFactory; +import org.apache.camel.component.rest.DummyRestProcessorFactory; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.model.rest.RestDefinition; +import org.apache.camel.model.rest.RestsDefinition; + +/** + * @version + */ +public class LoadRestFromXmlTest extends ContextTestSupport { + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("dummy-rest", new DummyRestConsumerFactory()); + jndi.bind("dummy-rest-api", new DummyRestProcessorFactory()); + return jndi; + } + + public void testLoadRouteFromXml() throws Exception { + assertNotNull("Existing foo route should be there", context.getRoute("foo")); + + assertEquals(2, context.getRoutes().size()); + + // test that existing route works + MockEndpoint foo = getMockEndpoint("mock:foo"); + foo.expectedBodiesReceived("Hello World"); + template.sendBody("direct:foo", "Hello World"); + foo.assertIsSatisfied(); + + // load rest from XML and add them to the existing camel context + InputStream is = getClass().getResourceAsStream("barRest.xml"); + RestsDefinition rests = context.loadRestsDefinition(is); + context.addRestDefinitions(rests.getRests()); + + for (final RestDefinition restDefinition : rests.getRests()) { + List<RouteDefinition> routeDefinitions = restDefinition.asRouteDefinition(context); + context.addRouteDefinitions(routeDefinitions); + } + + assertNotNull("Loaded rest route should be there", context.getRoute("route1")); + assertEquals(3, context.getRoutes().size()); + + // test that loaded route works + MockEndpoint bar = getMockEndpoint("mock:bar"); + bar.expectedBodiesReceived("Bye World"); + template.sendBody("seda:get-say-hello-bar", "Bye World"); + bar.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + restConfiguration().host("localhost").component("dummy-rest").apiContextPath("/api-docs"); + + from("direct:foo").routeId("foo") + .to("mock:foo"); + } + }; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/test/resources/org/apache/camel/impl/rest1.xml ---------------------------------------------------------------------- diff --git a/camel-core/src/test/resources/org/apache/camel/impl/rest1.xml b/camel-core/src/test/resources/org/apache/camel/impl/rest1.xml new file mode 100644 index 0000000..0256ad9 --- /dev/null +++ b/camel-core/src/test/resources/org/apache/camel/impl/rest1.xml @@ -0,0 +1,20 @@ +<?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. +--> +<rest id="foo" path="/say/hello" xmlns="http://camel.apache.org/schema/spring"> + <get uri="/bar"> + <to uri="mock:bar"/> + </get> +</rest> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/976ae698/camel-core/src/test/resources/org/apache/camel/model/barRest.xml ---------------------------------------------------------------------- diff --git a/camel-core/src/test/resources/org/apache/camel/model/barRest.xml b/camel-core/src/test/resources/org/apache/camel/model/barRest.xml new file mode 100644 index 0000000..3fa7207 --- /dev/null +++ b/camel-core/src/test/resources/org/apache/camel/model/barRest.xml @@ -0,0 +1,22 @@ +<?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. +--> +<rests xmlns="http://camel.apache.org/schema/spring"> + <rest id="bar" path="/say/hello"> + <get uri="/bar"> + <to uri="mock:bar"/> + </get> + </rest> +</rests> \ No newline at end of file