Experimental camel plugin which allows tracking camel flows. Example configuration attached. Because problems with dynamic interception strategies webconsole intercept strategy must be imported before context start
Signed-off-by: Lukasz Dywicki <luke@code-house.org>
git-svn-id: https://svn.apache.org/repos/asf/karaf/sandbox/webconsole/trunk@1165854 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/camel/pom.xml b/camel/pom.xml
new file mode 100644
index 0000000..7fb3ecb
--- /dev/null
+++ b/camel/pom.xml
@@ -0,0 +1,76 @@
+<?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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>webconsole</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.karaf.webconsole</groupId>
+ <artifactId>org.apache.karaf.webconsole.camel</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Karaf Webconsole Prototype :: Camel extension</name>
+ <version>1.0.0-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.karaf.webconsole</groupId>
+ <artifactId>org.apache.karaf.webconsole.core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ <version>${camel.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.3.5</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Import-Package>
+ !org.apache.karaf.webconsole.camel*,
+ *,
+ <!-- transient dependencies -->
+ org.ops4j.pax.wicket.api,
+ org.ops4j.pax.wicket.util,
+ org.ops4j.pax.wicket.util.proxy,
+ <!-- camel dependencies -->
+ org.apache.camel;version="[2.6,3)",
+ org.apache.camel.model;version="[2.6,3)",
+ org.apache.camel.spi;version="[2.6,3)",
+ org.apache.camel.processor;version="[2.6,3)"
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/CamelPage.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/CamelPage.java
new file mode 100644
index 0000000..dcd11d3
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/CamelPage.java
@@ -0,0 +1,7 @@
+package org.apache.karaf.webconsole.camel.internal;
+
+import org.apache.karaf.webconsole.core.page.SinglePage;
+
+public class CamelPage extends SinglePage {
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextModel.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextModel.java
new file mode 100644
index 0000000..c3e8d0c
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextModel.java
@@ -0,0 +1,30 @@
+package org.apache.karaf.webconsole.camel.internal.context;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.wicket.model.LoadableDetachableModel;
+
+public class CamelContextModel extends LoadableDetachableModel<CamelContext> {
+
+ private String name;
+ private List<CamelContext> contexts;
+
+ public CamelContextModel(List<CamelContext> contexts, CamelContext object) {
+ super(object);
+
+ this.contexts = contexts;
+ name = object.getName();
+ }
+
+ protected CamelContext load() {
+ for (CamelContext context : contexts) {
+ if (name.equals(context.getName())) {
+ return context;
+ }
+ }
+
+ throw new IllegalArgumentException("Camel context " + name + " not found");
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.java
new file mode 100644
index 0000000..67c2bc9
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.java
@@ -0,0 +1,76 @@
+package org.apache.karaf.webconsole.camel.internal.context;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.karaf.webconsole.camel.internal.CamelPage;
+import org.apache.karaf.webconsole.camel.internal.tracking.TraceContainer;
+import org.apache.karaf.webconsole.core.table.OrdinalColumn;
+import org.apache.karaf.webconsole.core.table.PropertyColumnExt;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.ops4j.pax.wicket.api.PaxWicketBean;
+import org.ops4j.pax.wicket.api.PaxWicketMountPoint;
+
+@PaxWicketMountPoint(mountPoint = "/camel/contexts")
+public class CamelContextsPage extends CamelPage {
+
+ @PaxWicketBean(name = "contexts")
+ private List<CamelContext> contexts;
+
+ @PaxWicketBean(name = "tracer")
+ private TraceContainer container;
+
+ public CamelContextsPage() {
+ @SuppressWarnings("unchecked")
+ IColumn<CamelContext>[] columns = new IColumn[] {
+ new OrdinalColumn<CamelContext>(),
+ new PropertyColumnExt<CamelContext>("Name", "name"),
+ new PropertyColumnExt<CamelContext>("Version", "version"),
+ new PropertyColumnExt<CamelContext>("Status", "status"),
+ new PropertyColumnExt<CamelContext>("Uptime", "uptime"),
+ new AbstractColumn<CamelContext>(Model.of("Message preview")) {
+ public void populateItem(Item<ICellPopulator<CamelContext>> cellItem, String componentId, IModel<CamelContext> rowModel) {
+ cellItem.add(new Label(componentId, "" + container.isTracePossible(rowModel.getObject())));
+ }
+ },
+ new AbstractColumn<CamelContext>(Model.of("Tracing enabled")) {
+ public void populateItem(Item<ICellPopulator<CamelContext>> cellItem, String componentId, IModel<CamelContext> rowModel) {
+ cellItem.add(new Label(componentId, "" + container.isTraced(rowModel.getObject())));
+ }
+ },
+ new AbstractColumn<CamelContext>(Model.of("Operations")) {
+ public void populateItem(Item<ICellPopulator<CamelContext>> cellItem, String componentId, IModel<CamelContext> rowModel) {
+ cellItem.add(new ContextActionsPanel(componentId, rowModel));
+ }
+ }
+ };
+
+ ISortableDataProvider<CamelContext> provider = new SortableDataProvider<CamelContext>() {
+ public Iterator<? extends CamelContext> iterator(int first, int count) {
+ return new ArrayList<CamelContext>(contexts).subList(first, first + count).iterator();
+ }
+
+ public int size() {
+ return contexts.size();
+ }
+
+ public IModel<CamelContext> model(CamelContext object) {
+ return new CamelContextModel(contexts, object);
+ }
+ };
+
+ add(new DefaultDataTable<CamelContext>("contexts", columns, provider, 20));
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/ContextActionsPanel.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/ContextActionsPanel.java
new file mode 100644
index 0000000..9351ea4
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/ContextActionsPanel.java
@@ -0,0 +1,69 @@
+package org.apache.karaf.webconsole.camel.internal.context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.karaf.webconsole.camel.internal.tracking.TraceContainer;
+import org.apache.karaf.webconsole.core.table.ActionsPanel;
+import org.apache.wicket.Session;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.IModel;
+import org.ops4j.pax.wicket.api.PaxWicketBean;
+
+public class ContextActionsPanel extends ActionsPanel<CamelContext> {
+
+ @PaxWicketBean(name = "tracer")
+ private TraceContainer container;
+
+ public ContextActionsPanel(String componentId, IModel<CamelContext> model) {
+ super(componentId, model);
+ }
+
+ @Override
+ protected List<Link> getLinks(CamelContext object, String id) {
+ List<Link> links = new ArrayList<Link>();
+
+ if (!object.isTracing()) {
+ Link link = new Link<CamelContext>(id) {
+ @Override
+ public void onClick() {
+ CamelContext context = (CamelContext) ContextActionsPanel.this.getDefaultModelObject();
+ context.setTracing(true);
+ setResponsePage(CamelContextsPage.class);
+ Session.get().info("Tracing enabled for context " + context.getName());
+ }
+ };
+ link.add(new Label("label", "Enable tracing"));
+ links.add(link);
+ } else {
+ Link link = new Link<CamelContext>(id) {
+ @Override
+ public void onClick() {
+ CamelContext context = (CamelContext) ContextActionsPanel.this.getDefaultModelObject();
+ context.setTracing(false);
+ setResponsePage(CamelContextsPage.class);
+ Session.get().info("Tracing disabled for context " + context.getName());
+ }
+ };
+ link.add(new Label("label", "Disable tracing"));
+ links.add(link);
+ }
+
+ if (container.isTracePossible(object)) {
+ Link link = new Link<CamelContext>(id) {
+ @Override
+ public void onClick() {
+ CamelContext context = (CamelContext) ContextActionsPanel.this.getDefaultModelObject();
+ setResponsePage(new DumpPage(container, context));
+ }
+ };
+ link.add(new Label("label", "View messages"));
+ links.add(link);
+ }
+
+ return links;
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/DumpPage.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/DumpPage.java
new file mode 100644
index 0000000..c5bbed7
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/context/DumpPage.java
@@ -0,0 +1,40 @@
+package org.apache.karaf.webconsole.camel.internal.context;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.karaf.webconsole.camel.internal.CamelPage;
+import org.apache.karaf.webconsole.camel.internal.tracking.TraceContainer;
+import org.apache.karaf.webconsole.camel.internal.tracking.Tracer;
+import org.apache.karaf.webconsole.core.table.map.MapDataProvider;
+import org.apache.karaf.webconsole.core.table.map.MapDataTable;
+import org.apache.wicket.Session;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+
+public class DumpPage extends CamelPage {
+
+ public DumpPage(TraceContainer container, CamelContext context) {
+ Tracer tracer = container.getTracer(context);
+ List<Map<String, Serializable>> info;
+
+ if (tracer != null) {
+ info = tracer.getInfo();
+ } else {
+ Session.get().warn("Tracer not found");
+ info = new ArrayList<Map<String,Serializable>>();
+ }
+
+ add(new ListView<Map<String, Serializable>>("properties", info) {
+ @Override
+ protected void populateItem(ListItem<Map<String, Serializable>> item) {
+ item.add(new MapDataTable<String, Serializable>("propertyMap", new MapDataProvider<String, Serializable>(item.getModelObject()), 20));
+ }
+ });
+
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/navigation/CamelConsoleTabProvider.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/navigation/CamelConsoleTabProvider.java
new file mode 100644
index 0000000..ec9b5dd
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/navigation/CamelConsoleTabProvider.java
@@ -0,0 +1,22 @@
+package org.apache.karaf.webconsole.camel.internal.navigation;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.karaf.webconsole.camel.internal.context.CamelContextsPage;
+import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
+import org.apache.karaf.webconsole.core.util.LinkUtils;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.link.Link;
+
+public class CamelConsoleTabProvider implements ConsoleTabProvider {
+
+ public List<Link<Page>> getItems(String componentId, String labelId) {
+ return Collections.emptyList();
+ }
+
+ public Link<Page> getModuleLink(String componentId, String labelId) {
+ return LinkUtils.createPageLink(componentId, labelId, "Camel", CamelContextsPage.class);
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/DefaultTracerContainer.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/DefaultTracerContainer.java
new file mode 100644
index 0000000..b3dbd60
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/DefaultTracerContainer.java
@@ -0,0 +1,29 @@
+package org.apache.karaf.webconsole.camel.internal.tracking;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+
+public class DefaultTracerContainer implements TraceContainer {
+
+ private Map<CamelContext, Tracer> tracers = Collections.synchronizedMap(new HashMap<CamelContext, Tracer>());
+
+ public boolean isTraced(CamelContext context) {
+ return isTracePossible(context) && context.isTracing();
+ }
+
+ public boolean isTracePossible(CamelContext context) {
+ return getTracer(context) != null;
+ }
+
+ public Tracer getTracer(CamelContext context) {
+ return tracers.get(context);
+ }
+
+ public void register(CamelContext context, Tracer tracer) {
+ tracers.put(context, tracer);
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceContainer.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceContainer.java
new file mode 100644
index 0000000..8dbaeab
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceContainer.java
@@ -0,0 +1,15 @@
+package org.apache.karaf.webconsole.camel.internal.tracking;
+
+import org.apache.camel.CamelContext;
+
+public interface TraceContainer {
+
+ Tracer getTracer(CamelContext context);
+
+ boolean isTraced(CamelContext context);
+
+ boolean isTracePossible(CamelContext context);
+
+ void register(CamelContext context, Tracer tracer);
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceInterceptStrategy.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceInterceptStrategy.java
new file mode 100644
index 0000000..bdc3b10
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceInterceptStrategy.java
@@ -0,0 +1,46 @@
+package org.apache.karaf.webconsole.camel.internal.tracking;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.LinkedBlockingDeque;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.InterceptStrategy;
+
+public class TraceInterceptStrategy implements InterceptStrategy, Tracer {
+
+ private LinkedBlockingDeque<Map<String, Serializable>> data = new LinkedBlockingDeque<Map<String,Serializable>>(20);
+ private TraceContainer container;
+
+ public TraceInterceptStrategy(TraceContainer container) {
+ this.container = container;
+ }
+
+ public Processor wrapProcessorInInterceptors(CamelContext context,
+ ProcessorDefinition<?> definition,
+ Processor target,
+ Processor nextTarget) throws Exception {
+
+ Map<String,Serializable> properties = Collections.synchronizedMap(new HashMap<String, Serializable>());
+ properties.put("context", context.getName());
+ properties.put("version", context.getVersion());
+
+ data.add(properties);
+
+ TraceProcessor tracer = new TraceProcessor(properties, target);
+ container.register(context, this);
+
+ return tracer;
+ }
+
+ public List<Map<String, Serializable>> getInfo() {
+ return new ArrayList<Map<String, Serializable>>(data);
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceProcessor.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceProcessor.java
new file mode 100644
index 0000000..1550858
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/TraceProcessor.java
@@ -0,0 +1,65 @@
+package org.apache.karaf.webconsole.camel.internal.tracking;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.processor.DelegateAsyncProcessor;
+
+public class TraceProcessor extends DelegateAsyncProcessor {
+
+ private Map<String, Serializable> properties;
+
+ public TraceProcessor(Map<String, Serializable> properties, Processor target) {
+ super(target);
+ this.properties = properties;
+ }
+
+ @Override
+ public boolean process(Exchange exchange, AsyncCallback callback) {
+
+ CamelContext context = exchange.getContext();
+ if (!context.isTracing()) {
+ return super.process(exchange, callback);
+ }
+
+ properties.put("exchangeId", exchange.getExchangeId());
+
+ properties.put("exchangeProperties", (Serializable) exchange.getProperties());
+ Message msg = exchange.getIn();
+ if (msg != null) {
+ properties.put("exchangeInId", msg.getMessageId());
+ properties.put("exchangeInHeaders", new HashMap(msg.getHeaders()));
+ Object body = msg.getBody();
+ if (body instanceof Serializable) {
+ properties.put("exchangeInBody", (Serializable) body);
+ } else {
+ properties.put("exchangeInBody", "- not serializable -");
+ }
+ } else {
+ properties.put("exchangeInId", null);
+ }
+
+ msg = exchange.getOut();
+ if (msg != null) {
+ properties.put("exchangeOutId", msg.getMessageId());
+ properties.put("exchangeOutHeaders", new HashMap(msg.getHeaders()));
+ Object body = msg.getBody();
+ if (body instanceof Serializable) {
+ properties.put("exchangeOutBody", (Serializable) body);
+ } else {
+ properties.put("exchangeOutBody", "- not serializable -");
+ }
+ } else {
+ properties.put("exchangeOutId", null);
+ }
+
+ return super.process(exchange, callback);
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/Tracer.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/Tracer.java
new file mode 100644
index 0000000..dd7f3c8
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/tracking/Tracer.java
@@ -0,0 +1,11 @@
+package org.apache.karaf.webconsole.camel.internal.tracking;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+public interface Tracer {
+
+ List<Map<String, Serializable>> getInfo();
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.java
new file mode 100644
index 0000000..7bdc37d
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.java
@@ -0,0 +1,35 @@
+package org.apache.karaf.webconsole.camel.internal.widget;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.karaf.webconsole.camel.internal.context.CamelContextsPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class CamelWidget extends Panel {
+
+ public CamelWidget(String id, List<CamelContext> contexts) {
+ super(id);
+
+// List<CamelContext> subList = new ArrayList<CamelContext>(contexts);
+// if (subList.size() > 4) {
+// subList = subList.subList(0, 4);
+// }
+ add(new Label("count", "" + contexts.size()));
+
+ add(new ListView<CamelContext>("contexts"/*, subList*/) {
+ @Override
+ protected void populateItem(ListItem<CamelContext> item) {
+ CamelContext model = item.getModelObject();
+ add(new Label("name", model.getName()));
+ }
+ });
+
+ add(new BookmarkablePageLink<CamelContextsPage>("management", CamelContextsPage.class));
+ }
+
+}
diff --git a/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidgetProvider.java b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidgetProvider.java
new file mode 100644
index 0000000..507bc91
--- /dev/null
+++ b/camel/src/main/java/org/apache/karaf/webconsole/camel/internal/widget/CamelWidgetProvider.java
@@ -0,0 +1,21 @@
+package org.apache.karaf.webconsole.camel.internal.widget;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.karaf.webconsole.core.widget.WidgetProvider;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class CamelWidgetProvider implements WidgetProvider {
+
+ private final List<CamelContext> contexts;
+
+ public CamelWidgetProvider(List<CamelContext> contexts) {
+ this.contexts = contexts;
+ }
+
+ public Panel getWidgetPanel(String id) {
+ return new CamelWidget(id, contexts);
+ }
+
+}
diff --git a/camel/src/main/resources/OSGI-INF/blueprint/camel.xml b/camel/src/main/resources/OSGI-INF/blueprint/camel.xml
new file mode 100644
index 0000000..3113b1e
--- /dev/null
+++ b/camel/src/main/resources/OSGI-INF/blueprint/camel.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <service interface="org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider">
+ <bean class="org.apache.karaf.webconsole.camel.internal.navigation.CamelConsoleTabProvider" />
+ </service>
+
+ <bean id="tracer" class="org.apache.karaf.webconsole.camel.internal.tracking.DefaultTracerContainer" />
+
+ <reference-list id="contexts" interface="org.apache.camel.CamelContext"/>
+
+ <service ref="widgetProvider" interface="org.apache.karaf.webconsole.core.widget.WidgetProvider">
+ <service-properties>
+ <entry key="intention" value="dashboard" />
+ </service-properties>
+ </service>
+
+ <bean id="widgetProvider" class="org.apache.karaf.webconsole.camel.internal.widget.CamelWidgetProvider">
+ <argument ref="contexts" />
+ </bean>
+
+ <service auto-export="interfaces">
+ <bean class="org.apache.karaf.webconsole.camel.internal.tracking.TraceInterceptStrategy">
+ <argument ref="tracer" />
+ </bean>
+ </service>
+
+</blueprint>
diff --git a/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.html b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.html
new file mode 100644
index 0000000..bccb76c
--- /dev/null
+++ b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/CamelContextsPage.html
@@ -0,0 +1,33 @@
+<?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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Karaf WebConsole</title>
+</head>
+<body>
+
+ <wicket:extend>
+ <h1>Deployed camel contexts</h1>
+
+ <table wicket:id="contexts" class="dataview" />
+
+ </wicket:extend>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/DumpPage.html b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/DumpPage.html
new file mode 100644
index 0000000..9f6d109
--- /dev/null
+++ b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/DumpPage.html
@@ -0,0 +1,39 @@
+<?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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Karaf WebConsole</title>
+</head>
+<body>
+
+ <wicket:extend>
+ <h1>Traced context details</h1>
+
+ <h2>Info from trace</h2>
+
+ <ul>
+ <li wicket:id="properties">
+ <table wicket:id="propertyMap" class="dataview" />
+ </li>
+ </ul>
+
+ </wicket:extend>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/TracePage.html b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/TracePage.html
new file mode 100644
index 0000000..11618b1
--- /dev/null
+++ b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/context/TracePage.html
@@ -0,0 +1,40 @@
+<?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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Karaf WebConsole</title>
+</head>
+<body>
+
+ <wicket:extend>
+ <h1>Deployed camel contexts</h1>
+
+ <p>
+ A tracer has been found: <label wicket:id="tracer"></label>.
+ </p>
+
+ <h2>Attached tracers</h2>
+ <ul>
+ <li wicket:id="tracers">ctx-1</li>
+ </ul>
+
+ </wicket:extend>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.html b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.html
new file mode 100644
index 0000000..1923a18
--- /dev/null
+++ b/camel/src/main/resources/org/apache/karaf/webconsole/camel/internal/widget/CamelWidget.html
@@ -0,0 +1,45 @@
+<?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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Karaf WebConsole</title>
+</head>
+<body>
+
+ <wicket:panel>
+ <div class="grid_6 widget">
+ <h1>Deployed camel contexts</h1>
+
+ <p>You have <span wicket:id="count">13</span> camel contexts deployed. First four are:</p>
+
+ <table class="dataview">
+ <tr>
+ <th>Name</th>
+ </tr>
+ <tr wicket:id="contexts">
+ <td><span wicket:id="name">.test-context</span></td>
+ </tr>
+ </table>
+
+ <a href="#" wicket:id="management">Go to context management</a>
+ </div>
+ </wicket:panel>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/camel/test-context.xml b/camel/test-context.xml
new file mode 100644
index 0000000..e7bafb5
--- /dev/null
+++ b/camel/test-context.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <camelContext id="timer-test" xmlns="http://camel.apache.org/schema/blueprint">
+ <route>
+ <from uri="timer:test" />
+ <to uri="log:test" />
+ </route>
+ </camelContext>
+
+ <reference id="interceptStragety" interface="org.apache.camel.spi.InterceptStrategy" />
+
+</blueprint>
diff --git a/pom.xml b/pom.xml
index 12ec443..a03fe43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,7 @@
<ops4j.paxwicket.version>0.8.0-SNAPSHOT</ops4j.paxwicket.version>
<karaf.version>2.2.2</karaf.version>
<nmr.version>1.4.0</nmr.version>
+ <camel.version>[2.6.0,3)</camel.version>
</properties>
<modules>
@@ -43,6 +44,7 @@
<module>karaf</module>
<module>features</module>
<module>servicemix</module>
+ <module>camel</module>
<module>examples</module>
<module>manual</module>