This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-karaf.git
commit 8d239dffb36a8ef3498e89f4dc812bb47ebbb91f Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Tue Mar 24 08:34:21 2020 +0100 Added camel-kura to components --- components/camel-kura/pom.xml | 125 +++++++++ .../services/org/apache/camel/other.properties | 7 + .../camel-kura/src/generated/resources/kura.json | 14 + components/camel-kura/src/main/docs/kura.adoc | 298 +++++++++++++++++++++ .../apache/camel/component/kura/KuraRouter.java | 149 +++++++++++ .../camel/component/kura/KuraRouterTest.java | 144 ++++++++++ .../src/test/resources/log4j2.properties | 30 +++ components/camel-kura/src/test/resources/route.xml | 25 ++ components/pom.xml | 1 + 9 files changed, 793 insertions(+) diff --git a/components/camel-kura/pom.xml b/components/camel-kura/pom.xml new file mode 100644 index 0000000..8b1f4af --- /dev/null +++ b/components/camel-kura/pom.xml @@ -0,0 +1,125 @@ +<?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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel.karaf</groupId> + <artifactId>components</artifactId> + <version>3.2.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-kura</artifactId> + <packaging>jar</packaging> + <name>Camel :: Kura</name> + <description>Using Camel with Eclipse Kura (OSGi)</description> + + <properties> + <firstVersion>2.15.0</firstVersion> + <label>iot,osgi</label> + + </properties> + + <dependencies> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-support</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core-osgi</artifactId> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.framework</artifactId> + <version>${felix-framework-version}</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.configadmin</artifactId> + <version>${felix-configadmin-version}</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr</artifactId> + <version>${felix-scr-version}</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <version>${felix-scr-annotations-version}</version> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-xml-jaxb</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-mock</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-direct</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project> diff --git a/components/camel-kura/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/components/camel-kura/src/generated/resources/META-INF/services/org/apache/camel/other.properties new file mode 100644 index 0000000..343cb4c --- /dev/null +++ b/components/camel-kura/src/generated/resources/META-INF/services/org/apache/camel/other.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +name=kura +groupId=org.apache.camel +artifactId=camel-kura +version=3.2.0-SNAPSHOT +projectName=Camel :: Kura +projectDescription=Using Camel with Eclipse Kura (OSGi) diff --git a/components/camel-kura/src/generated/resources/kura.json b/components/camel-kura/src/generated/resources/kura.json new file mode 100644 index 0000000..1d8e69d --- /dev/null +++ b/components/camel-kura/src/generated/resources/kura.json @@ -0,0 +1,14 @@ +{ + "other": { + "kind": "other", + "name": "kura", + "title": "Kura", + "description": "Using Camel with Eclipse Kura (OSGi)", + "deprecated": false, + "firstVersion": "2.15.0", + "label": "iot,osgi", + "groupId": "org.apache.camel", + "artifactId": "camel-kura", + "version": "3.2.0-SNAPSHOT" + } +} diff --git a/components/camel-kura/src/main/docs/kura.adoc b/components/camel-kura/src/main/docs/kura.adoc new file mode 100644 index 0000000..43945d5 --- /dev/null +++ b/components/camel-kura/src/main/docs/kura.adoc @@ -0,0 +1,298 @@ +[[Kura-EclipseKuracomponent]] += Eclipse Kura component + +*Since Camel 2.15* + +This documentation page covers the integration options of Camel with the +https://eclipse.org/kura/[Eclipse Kura] M2M gateway. The common reason +to deploy Camel routes into the Eclipse Kura is to provide enterprise +integration patterns and Camel components to the messaging M2M gateway. +For example you might want to install Kura on Raspberry PI, then read +temperature from the sensor attached to that Raspberry PI using Kura +services and finally forward the current temperature value to your data +center service using Camel EIP and components. + +[[Kura-KuraRouteractivator]] +== KuraRouter activator + +Bundles deployed to the Eclipse Kura are usually +http://eclipse.github.io/kura/doc/hello-example.html#create-java-class[developed +as bundle activators]. So the easiest way to deploy Apache Camel routes +into the Kura is to create an OSGi bundle containing the class extending +`org.apache.camel.kura.KuraRouter` class: + +[source,java] +------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + from("timer:trigger"). + to("netty-http:http://app.mydatacenter.com/api"); + } + +} +------------------------------------------------------- + +Keep in mind that `KuraRouter` implements +the `org.osgi.framework.BundleActivator` interface, so you need to +register its `start` and `stop` lifecycle methods +while http://eclipse.github.io/kura/doc/hello-example.html#create-component-class[creating +Kura bundle component class]. + +Kura router starts its own OSGi-aware `CamelContext`. It means that for +every class extending `KuraRouter`, there will be a dedicated +`CamelContext` instance. Ideally we recommend to deploy one `KuraRouter` +per OSGi bundle. + +[[Kura-DeployingKuraRouter]] +=== Deploying KuraRouter + +Bundle containing your Kura router class should import the following +packages in the OSGi manifest: + +[source,xml] +-------------------------------------------------------------------------------------------------------------------- +Import-Package: org.osgi.framework;version="1.3.0", + org.slf4j;version="1.6.4", + org.apache.camel,org.apache.camel.impl,org.apache.camel.core.osgi,org.apache.camel.builder,org.apache.camel.model, + org.apache.camel.component.kura +-------------------------------------------------------------------------------------------------------------------- + +Keep in mind that you don't have to import every Camel component bundle +you plan to use in your routes, as Camel components are resolved as the +services on the runtime level. + +Before you deploy your router bundle, be sure that you have deployed +(and started) the following Camel core bundles (using Kura GoGo +shell)... + +[source,xml] +----------------------------------------------------------------------------------------------------------- +install file:///home/user/.m2/repository/org/apache/camel/camel-core/2.15.0/camel-core-2.15.0.jar +start <camel-core-bundle-id> +install file:///home/user/.m2/repository/org/apache/camel/camel-core-osgi/2.15.0/camel-core-osgi-2.15.0.jar +start <camel-core-osgi-bundle-id> +install file:///home/user/.m2/repository/org/apache/camel/camel-kura/2.15.0/camel-kura-2.15.0.jar +start <camel-kura-bundle-id> +----------------------------------------------------------------------------------------------------------- + +...and all the components you plan to use in your routes: + +[source,xml] +----------------------------------------------------------------------------------------------------- +install file:///home/user/.m2/repository/org/apache/camel/camel-stream/2.15.0/camel-stream-2.15.0.jar +start <camel-stream-bundle-id> +----------------------------------------------------------------------------------------------------- + +Then finally deploy your router bundle: + +[source,xml] +---------------------------------------------------------------------------------- +install file:///home/user/.m2/repository/com/example/myrouter/1.0/myrouter-1.0.jar +start <your-bundle-id> +---------------------------------------------------------------------------------- + +[[Kura-KuraRouterutilities]] +=== KuraRouter utilities + + Kura router base class provides many useful utilities. This section +explores each of them. + +[[Kura-SLF4Jlogger]] +==== SLF4J logger + +Kura uses SLF4J facade for logging purposes. Protected member `log` +returns SLF4J logger instance associated with the given Kura router. + +[source,java] +---------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + log.info("Configuring Camel routes!"); + ... + } + +} +---------------------------------------------- + +[[Kura-BundleContext]] +==== BundleContext + +Protected member `bundleContext` returns bundle context associated with +the given Kura router. + +[source,java] +--------------------------------------------------------------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + ServiceReference<MyService> serviceRef = bundleContext.getServiceReference(LogService.class.getName()); + MyService myService = bundleContext.getService(serviceRef); + ... + } + +} +--------------------------------------------------------------------------------------------------------------- + +[[Kura-CamelContext]] +==== CamelContext + +Protected member `camelContext` is the `CamelContext` associated with +the given Kura router. + +[source,java] +---------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + camelContext.getStatus(); + ... + } + +} +---------------------------------------------- + +[[Kura-ProducerTemplate]] +==== ProducerTemplate + +Protected member `producerTemplate` is the `ProducerTemplate` instance +associated with the given Camel context. + +[source,java] +----------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + producerTemplate.sendBody("jms:temperature", 22.0); + ... + } + +} +----------------------------------------------------------- + +[[Kura-ConsumerTemplate]] +==== ConsumerTemplate + +Protected member `consumerTemplate` is the `ConsumerTemplate` instance +associated with the given Camel context. + +[source,java] +-------------------------------------------------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + double currentTemperature = producerTemplate.receiveBody("jms:temperature", Double.class); + ... + } + +} +-------------------------------------------------------------------------------------------------- + +[[Kura-OSGiserviceresolver]] +==== OSGi service resolver + +OSGi service resolver (`service(Class<T> serviceType)`) can be used to +easily retrieve service by type from the OSGi bundle context. + +[source,java] +------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + MyService myService = service(MyService.class); + ... + } + +} +------------------------------------------------------- + +If service is not found, a `null` value is returned. If you want your +application to fail if the service is not available, use +`requiredService(Class)` method instead. The `requiredService` throws +`IllegalStateException` if a service cannot be found. + +[source,java] +--------------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + MyService myService = requiredService(MyService.class); + ... + } + +} +--------------------------------------------------------------- + +[[Kura-KuraRouteractivatorcallbacks]] +=== KuraRouter activator callbacks + +Kura router comes with the lifecycle callbacks that can be used to +customize the way the Camel router works. For example to configure the +`CamelContext` instance associated with the router just before the +former is started, override `beforeStart` method of the `KuraRouter` +class: + +[source,java] +-------------------------------------------------------------------------- +public class MyKuraRouter extends KuraRouter { + + ... + + protected void beforeStart(CamelContext camelContext) { + OsgiDefaultCamelContext osgiContext = (OsgiCamelContext) camelContext; + osgiContext.setName("NameOfTheRouter"); + } + +} +-------------------------------------------------------------------------- + +[[Kura-LoadingXMLroutesfromConfigurationAdmin]] +=== Loading XML routes from ConfigurationAdmin + +Sometimes it is desired to read the XML definition of the routes from +the server configuration. This a common scenario for IoT gateways where +over-the-air redeployment cost may be significant. To address this +requirement each `KuraRouter` looks for the +`kura.camel.BUNDLE-SYMBOLIC-NAME.route` property from the `kura.camel` +PID using the OSGi ConfigurationAdmin. This approach allows you to +define Camel XML routes file per deployed `KuraRouter`. In order to +update a route, just edit an appropriate configuration property and +restart a bundle associated with it. The content of +the `kura.camel.BUNDLE-SYMBOLIC-NAME.route` property is expected to be +Camel XML route file, for example: + +[source,java] +------------------------------------------------------ +<routes xmlns="http://camel.apache.org/schema/spring"> + <route id="loaded"> + <from uri="direct:bar"/> + <to uri="mock:bar"/> + </route> +</routes> +------------------------------------------------------ + + + +[[Kura-DeployingKurarouterasadeclarativeOSGiservice]] +=== Deploying Kura router as a declarative OSGi service + +If you would like to deploy your Kura router as a declarative OSGi +service, you can use `activate` and `deactivate` methods provided by +`KuraRouter`. + +[source,java] +---------------------------------------------------------------------------------------------------------------------------------------------- +<scr:component name="org.eclipse.kura.example.camel.MyKuraRouter" activate="activate" deactivate="deactivate" enabled="true" immediate="true"> + <implementation class="org.eclipse.kura.example.camel.MyKuraRouter"/> +</scr:component> +---------------------------------------------------------------------------------------------------------------------------------------------- + diff --git a/components/camel-kura/src/main/java/org/apache/camel/component/kura/KuraRouter.java b/components/camel-kura/src/main/java/org/apache/camel/component/kura/KuraRouter.java new file mode 100644 index 0000000..6f48073 --- /dev/null +++ b/components/camel-kura/src/main/java/org/apache/camel/component/kura/KuraRouter.java @@ -0,0 +1,149 @@ +/* + * 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.component.kura; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.ConsumerTemplate; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.core.osgi.OsgiDefaultCamelContext; +import org.apache.camel.model.Model; +import org.apache.camel.model.RoutesDefinition; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class KuraRouter extends RouteBuilder implements BundleActivator { + + // Member collaborators + + protected final Logger log = LoggerFactory.getLogger(getClass()); + + protected BundleContext bundleContext; + + protected CamelContext camelContext; + + protected ProducerTemplate producerTemplate; + + protected ConsumerTemplate consumerTemplate; + + // Lifecycle + + @Override + public void start(BundleContext bundleContext) throws Exception { + try { + this.bundleContext = bundleContext; + log.debug("Initializing bundle {}.", bundleContext.getBundle().getBundleId()); + camelContext = createCamelContext(); + + camelContext.addRoutes(this); + ConfigurationAdmin configurationAdmin = requiredService(ConfigurationAdmin.class); + Configuration camelKuraConfig = configurationAdmin.getConfiguration(camelXmlRoutesPid()); + if (camelKuraConfig != null && camelKuraConfig.getProperties() != null) { + Object routePropertyValue = camelKuraConfig.getProperties().get(camelXmlRoutesProperty()); + if (routePropertyValue != null) { + InputStream routesXml = new ByteArrayInputStream(routePropertyValue.toString().getBytes()); + ExtendedCamelContext ecc = camelContext.adapt(ExtendedCamelContext.class); + RoutesDefinition routes = (RoutesDefinition) ecc.getXMLRoutesDefinitionLoader().loadRoutesDefinition(ecc, routesXml); + camelContext.getExtension(Model.class).addRouteDefinitions(routes.getRoutes()); + } + } + + beforeStart(camelContext); + log.debug("About to start Camel Kura router: {}", getClass().getName()); + camelContext.start(); + producerTemplate = camelContext.createProducerTemplate(); + consumerTemplate = camelContext.createConsumerTemplate(); + log.debug("Bundle {} started.", bundleContext.getBundle().getBundleId()); + } catch (Throwable e) { + String errorMessage = "Problem when starting Kura module " + getClass().getName() + ":"; + log.warn(errorMessage, e); + + // Print error to the Kura console. + System.err.println(errorMessage); + e.printStackTrace(); + + throw e; + } + } + + @Override + public void stop(BundleContext bundleContext) throws Exception { + log.debug("Stopping bundle {}.", bundleContext.getBundle().getBundleId()); + camelContext.stop(); + log.debug("Bundle {} stopped.", bundleContext.getBundle().getBundleId()); + } + + protected void activate(ComponentContext componentContext, Map<String, Object> properties) throws Exception { + start(componentContext.getBundleContext()); + } + + protected void deactivate(ComponentContext componentContext) throws Exception { + stop(componentContext.getBundleContext()); + } + + // Callbacks + + @Override + public void configure() throws Exception { + log.debug("No programmatic routes configuration found."); + } + + protected CamelContext createCamelContext() { + return new OsgiDefaultCamelContext(bundleContext); + } + + protected void beforeStart(CamelContext camelContext) { + log.debug("Empty KuraRouter CamelContext before start configuration - skipping."); + } + + // API Helpers + + protected <T> T service(Class<T> serviceType) { + ServiceReference reference = bundleContext.getServiceReference(serviceType.getName()); + return reference == null ? null : (T) bundleContext.getService(reference); + } + + protected <T> T requiredService(Class<T> serviceType) { + ServiceReference reference = bundleContext.getServiceReference(serviceType.getName()); + if (reference == null) { + throw new IllegalStateException("Cannot find service: " + serviceType.getName()); + } + return (T) bundleContext.getService(reference); + } + + // Private helpers + + protected String camelXmlRoutesPid() { + return "kura.camel"; + } + + protected String camelXmlRoutesProperty() { + return "kura.camel." + bundleContext.getBundle().getSymbolicName() + ".route"; + } + +} diff --git a/components/camel-kura/src/test/java/org/apache/camel/component/kura/KuraRouterTest.java b/components/camel-kura/src/test/java/org/apache/camel/component/kura/KuraRouterTest.java new file mode 100644 index 0000000..7cb653b --- /dev/null +++ b/components/camel-kura/src/test/java/org/apache/camel/component/kura/KuraRouterTest.java @@ -0,0 +1,144 @@ +/* + * 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.component.kura; + +import java.nio.charset.StandardCharsets; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.apache.camel.CamelContext; +import org.apache.camel.ServiceStatus; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.model.Model; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; + +public class KuraRouterTest extends Assert { + + TestKuraRouter router = new TestKuraRouter(); + + BundleContext bundleContext = mock(BundleContext.class, RETURNS_DEEP_STUBS); + + ConfigurationAdmin configurationAdmin = mock(ConfigurationAdmin.class); + + Configuration configuration = mock(Configuration.class); + + @Before + public void before() throws Exception { + given(bundleContext.getBundle().getVersion().toString()).willReturn("version"); + given(bundleContext.getBundle().getSymbolicName()).willReturn("symbolic_name"); + given(bundleContext.getService(any(ServiceReference.class))).willReturn(configurationAdmin); + + router.start(bundleContext); + } + + @After + public void after() throws Exception { + router.stop(bundleContext); + } + + @Test + public void shouldCloseCamelContext() throws Exception { + // When + router.stop(bundleContext); + + // Then + Assert.assertEquals(ServiceStatus.Stopped, router.camelContext.getStatus()); + } + + @Test + public void shouldStartCamelContext() throws Exception { + // Given + String message = "foo"; + MockEndpoint mockEndpoint = router.camelContext.getEndpoint("mock:test", MockEndpoint.class); + mockEndpoint.expectedBodiesReceived(message); + + // When + router.producerTemplate.sendBody("direct:start", message); + + // Then + mockEndpoint.assertIsSatisfied(); + } + + @Test + public void shouldCreateConsumerTemplate() throws Exception { + assertNotNull(router.consumerTemplate); + } + + @Test + public void shouldReturnNoService() { + given(bundleContext.getServiceReference(any(String.class))).willReturn(null); + assertNull(router.service(ConfigurationAdmin.class)); + } + + @Test + public void shouldReturnService() { + assertNotNull(router.service(ConfigurationAdmin.class)); + } + + @Test(expected = IllegalStateException.class) + public void shouldValidateLackOfService() { + given(bundleContext.getServiceReference(any(String.class))).willReturn(null); + router.requiredService(ConfigurationAdmin.class); + } + + @Test + public void shouldLoadXmlRoutes() throws Exception { + // Given + given(configurationAdmin.getConfiguration(anyString())).willReturn(configuration); + Dictionary<String, Object> properties = new Hashtable<>(); + String routeDefinition = IOUtils.toString(getClass().getResource("/route.xml"), StandardCharsets.UTF_8); + properties.put("kura.camel.symbolic_name.route", routeDefinition); + given(configuration.getProperties()).willReturn(properties); + + // When + router.start(router.bundleContext); + + // Then + assertNotNull(router.camelContext.getExtension(Model.class).getRouteDefinition("loaded")); + } + + static class TestKuraRouter extends KuraRouter { + + @Override + public void configure() throws Exception { + from("direct:start").to("mock:test"); + } + + @Override + protected CamelContext createCamelContext() { + return new DefaultCamelContext(); + } + + } + +} + diff --git a/components/camel-kura/src/test/resources/log4j2.properties b/components/camel-kura/src/test/resources/log4j2.properties new file mode 100644 index 0000000..d3198e9 --- /dev/null +++ b/components/camel-kura/src/test/resources/log4j2.properties @@ -0,0 +1,30 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +appender.console.type = Console +appender.console.name = console +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = %d %-5p %c{1} - %m %n +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-kura.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d %-5p %c{1} - %m %n +logger.kura.name = org.apache.camel.component.kura +logger.kura.level = DEBUG +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file diff --git a/components/camel-kura/src/test/resources/route.xml b/components/camel-kura/src/test/resources/route.xml new file mode 100644 index 0000000..3999ef3 --- /dev/null +++ b/components/camel-kura/src/test/resources/route.xml @@ -0,0 +1,25 @@ +<?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="http://camel.apache.org/schema/spring"> + <route id="loaded"> + <from uri="direct:bar"/> + <to uri="mock:bar"/> + </route> +</routes> diff --git a/components/pom.xml b/components/pom.xml index 1914ce9..19a1315 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -31,6 +31,7 @@ <packaging>pom</packaging> <modules> + <module>camel-kura</module> <module>camel-paxlogging</module> </modules>