/******************************************************************************* * Copyright (c) 2016 Red Hat Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat Inc - initial API and implementation *******************************************************************************/ package org.eclipse.kura.example.camel.quickstart; import static java.util.Collections.singletonMap; import static org.eclipse.kura.camel.component.Configuration.asInt; import java.util.Map; import java.util.Random; import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.eclipse.kura.camel.cloud.KuraCloudComponent; import org.eclipse.kura.camel.component.Configuration; import org.eclipse.kura.camel.runner.CamelRunner; import org.eclipse.kura.camel.runner.CamelRunner.Builder; import org.eclipse.kura.camel.runner.ServiceConsumer; import org.eclipse.kura.cloud.CloudService; import org.eclipse.kura.configuration.ConfigurableComponent; import org.eclipse.kura.message.KuraPayload; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Example of a Kura Camel application based on the Camel Java DSL */ public class GatewayRouterJava implements ConfigurableComponent { private static final Logger logger = LoggerFactory.getLogger(GatewayRouterJava.class); /** * A RouterBuilder instance which has no routes */ private static final RouteBuilder NO_ROUTES = new RouteBuilder() { @Override public void configure() throws Exception { } }; private CamelRunner camel; private String cloudServiceFilter; public void start(final Map<String, Object> properties) throws Exception { logger.info("Start: {}", properties); // create new filter and instance final String cloudServiceFilter = makeCloudServiceFilter(properties); this.camel = createCamelRunner(cloudServiceFilter); // set routes this.camel.setRoutes(fromProperties(properties)); // start this.camel.start(); } public void updated(final Map<String, Object> properties) throws Exception { logger.info("Updating: {}", properties); final String cloudServiceFilter = makeCloudServiceFilter(properties); if (!this.cloudServiceFilter.equals(cloudServiceFilter)) { // update the routes and the filter // stop the camel context first this.camel.stop(); // create a new camel runner, with new dependencies this.camel = createCamelRunner(cloudServiceFilter); // set the routes this.camel.setRoutes(fromProperties(properties)); // and restart again this.camel.start(); } else { // only update the routes, this is done without restarting the context this.camel.setRoutes(fromProperties(properties)); } } public void stop() throws Exception { if (this.camel != null) { this.camel.stop(); this.camel = null; } } private CamelRunner createCamelRunner(final String fullFilter) throws InvalidSyntaxException { final BundleContext ctx = FrameworkUtil.getBundle(GatewayRouterJava.class).getBundleContext(); this.cloudServiceFilter = fullFilter; // create a new camel CamelRunner.Builder final Builder builder = new CamelRunner.Builder(); // add service dependency builder.dependOn(ctx, FrameworkUtil.createFilter(fullFilter), new ServiceConsumer<CloudService, CamelContext>() { @Override public void consume(final CamelContext context, final CloudService service) { context.addComponent("cloud", new KuraCloudComponent(context, service)); } }); // return un-started instance return builder.build(); } /** * Construct an OSGi filter for a cloud service instance * * @param properties * the properties to read from * @return the OSGi filter selecting the cloud service instance */ private static String makeCloudServiceFilter(final Map<String, Object> properties) { final String filterPid = Configuration.asStringNotEmpty(properties, "cloudService", "org.eclipse.kura.cloud.CloudService"); final String fullFilter = String.format("(&(%s=%s)(kura.service.pid=%s))", Constants.OBJECTCLASS, CloudService.class.getName(), filterPid); return fullFilter; } /** * Create a new RouteBuilder instance from the properties * * @param properties * the properties to read from * @return the new instance of RouteBuilder */ protected RouteBuilder fromProperties(final Map<String, Object> properties) { if (!Configuration.asBoolean(properties, "enabled")) { return NO_ROUTES; } final int maxTemp = asInt(properties, "temperature.max", 20); return new RouteBuilder() { @Override public void configure() throws Exception { from("timer://heartbeat").process(new Processor() { @Override public void process(Exchange exchange) throws Exception { final int value = new Random().nextInt(maxTemp); final Map<String, Integer> data = singletonMap("temperature", value); exchange.getIn().setBody(data); } }) // .convertBodyTo(KuraPayload.class) // .to("cloud:myapp/topic").id("temp-heartbeat"); from("cloud:myapp/topic") // .choice() // .when(simple("${body.metrics()[temperature]} < 10")).to("log:lessThanTen") // .when(simple("${body.metrics()[temperature]} == 10")).to("log:equalToTen") // .otherwise().to("log:greaterThanTen") // .id("test-log"); from("timer://xmltopic").process(new Processor() { @Override public void process(Exchange exchange) throws Exception { KuraPayload payload = new KuraPayload(); payload.addMetric("temperature", new Random().nextInt(20)); exchange.getIn().setBody(payload); } }).to("cloud:myapp/xmltopic"); } }; } }