CAMEL-8223: Inflight repository to allow browsing of current inflight exchanges


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f812a45e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f812a45e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f812a45e

Branch: refs/heads/master
Commit: f812a45e16cf72ccd2feb7827b72427909fdaf56
Parents: 416654d
Author: Claus Ibsen <davscl...@apache.org>
Authored: Fri Jan 9 12:50:25 2015 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Fri Jan 9 13:41:46 2015 +0100

----------------------------------------------------------------------
 .../camel/impl/DefaultInflightRepository.java   |   8 +
 .../apache/camel/spi/InflightRepository.java    |   2 +-
 .../camel/commands/AbstractCamelCommand.java    |   8 +
 .../commands/AbstractLocalCamelController.java  |  53 +++++++
 .../apache/camel/commands/CamelController.java  |  11 ++
 .../camel/commands/ContextInflightCommand.java  | 150 +++++++++++++++++++
 .../camel/commands/ContextInfoCommand.java      |   8 -
 .../jolokia/DefaultJolokiaCamelController.java  |  33 ++++
 .../karaf/commands/CamelCommandSupport.java     |   8 -
 .../camel/karaf/commands/ContextInflight.java   |  43 ++++++
 .../OSGI-INF/blueprint/camel-commands.xml       |   9 ++
 11 files changed, 316 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/camel-core/src/main/java/org/apache/camel/impl/DefaultInflightRepository.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultInflightRepository.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultInflightRepository.java
index 5abe8e8..ab0079b 100644
--- 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultInflightRepository.java
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultInflightRepository.java
@@ -106,6 +106,14 @@ public class DefaultInflightRepository extends 
ServiceSupport implements Infligh
                     return Long.compare(d1, d2);
                 }
             });
+        } else {
+            // else sort by exchange id
+            Collections.sort(values, new Comparator<Exchange>() {
+                @Override
+                public int compare(Exchange e1, Exchange e2) {
+                    return e1.getExchangeId().compareTo(e2.getExchangeId());
+                }
+            });
         }
 
         for (Exchange exchange : values) {

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/camel-core/src/main/java/org/apache/camel/spi/InflightRepository.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/spi/InflightRepository.java 
b/camel-core/src/main/java/org/apache/camel/spi/InflightRepository.java
index 0fc313f..f7aad78 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/InflightRepository.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/InflightRepository.java
@@ -140,7 +140,7 @@ public interface InflightRepository extends StaticService {
      *
      * @param limit maximum number of entries to return
      * @param sortByLongestDuration to sort by the longest duration. Set to 
<tt>true</tt> to include the exchanges that has been inflight the longest time,
-     *                              set to <tt>false</tt> to include the 
exchanges in unspecified order.
+     *                              set to <tt>false</tt> to sort by exchange 
id
      */
     Collection<InflightExchange> browse(int limit, boolean 
sortByLongestDuration);
 

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelCommand.java
index 03fa4e3..55035b8 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelCommand.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelCommand.java
@@ -31,4 +31,12 @@ public abstract class AbstractCamelCommand implements 
CamelCommand {
         }
     }
 
+    public String safeNull(Object s) {
+        if (ObjectHelper.isEmpty(s)) {
+            return "";
+        } else {
+            return s.toString();
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
index 9ea4dc3..e2863a3 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
@@ -17,6 +17,7 @@
 package org.apache.camel.commands;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -28,6 +29,8 @@ import java.util.Properties;
 import java.util.Set;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
@@ -163,6 +166,56 @@ public abstract class AbstractLocalCamelController extends 
AbstractCamelControll
         return null;
     }
 
+    @SuppressWarnings("unchecked")
+    public List<Map<String, Object>> browseInflightExchanges(String 
camelContextName, int limit, boolean sortByLongestDuration) throws Exception {
+        CamelContext context = this.getLocalCamelContext(camelContextName);
+        if (context == null) {
+            return null;
+        }
+
+        List<Map<String, Object>> answer = new ArrayList<Map<String, 
Object>>();
+
+        ManagementAgent agent = 
context.getManagementStrategy().getManagementAgent();
+        if (agent != null) {
+            MBeanServer mBeanServer = agent.getMBeanServer();
+            ObjectName on = null;
+            Set<ObjectName> set = mBeanServer.queryNames(new 
ObjectName(agent.getMBeanObjectDomainName() + 
":type=services,name=DefaultInflightRepository,*"), null);
+            if (set.size() == 1) {
+                on = set.iterator().next();
+            }
+            if (mBeanServer.isRegistered(on)) {
+                TabularData list = (TabularData) mBeanServer.invoke(on, 
"browse", new Object[]{limit, sortByLongestDuration}, new String[]{"int", 
"boolean"});
+                Collection<CompositeData> values = (Collection<CompositeData>) 
list.values();
+                for (CompositeData data : values) {
+                    Map<String, Object> row = new LinkedHashMap<String, 
Object>();
+                    Object exchangeId = data.get("exchangeId");
+                    if (exchangeId != null) {
+                        row.put("exchangeId", exchangeId);
+                    }
+                    Object routeId = data.get("routeId");
+                    if (routeId != null) {
+                        row.put("routeId", routeId);
+                    }
+                    Object nodeId = data.get("nodeId");
+                    if (nodeId != null) {
+                        row.put("nodeId", nodeId);
+                    }
+                    Object duration = data.get("duration");
+                    if (duration != null) {
+                        row.put("duration", duration);
+                    }
+                    Object elapsed = data.get("elapsed");
+                    if (elapsed != null) {
+                        row.put("elapsed", elapsed);
+                    }
+                    answer.add(row);
+                }
+            }
+        }
+
+        return answer;
+    }
+
     public void startContext(String camelContextName) throws Exception {
         CamelContext context = getLocalCamelContext(camelContextName);
         if (context != null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
index dd07768..5ab7e8e 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
@@ -54,6 +54,17 @@ public interface CamelController {
     String getCamelContextStatsAsXml(String camelContextName, boolean 
fullStats, boolean includeProcessors) throws Exception;
 
     /**
+     * Browses the inflight exchanges
+     *
+     * @param camelContextName        the Camel context.
+     * @param limit                   maximum number of exchanges to return
+     * @param sortByLongestDuration   <tt>true</tt> to sort by longest 
duration, <tt>false</tt> to sort by exchange id
+     * @return a list of key/value pairs with inflight exchange information
+     * @throws java.lang.Exception can be thrown
+     */
+    List<Map<String, Object>> browseInflightExchanges(String camelContextName, 
int limit, boolean sortByLongestDuration) throws Exception;
+
+    /**
      * Starts the given Camel context.
      *
      * @param camelContextName the Camel context.

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInflightCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInflightCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInflightCommand.java
new file mode 100644
index 0000000..9c24480
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInflightCommand.java
@@ -0,0 +1,150 @@
+/**
+ * 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.commands;
+
+import java.io.PrintStream;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Command to display inflight exchange information
+ */
+public class ContextInflightCommand extends AbstractContextCommand {
+
+    private static final String EXCHANGE_COLUMN_LABEL = "ExchangeId";
+    private static final String ROUTE_COLUMN_LABEL = "Route";
+    private static final String NODE_COLUMN_LABEL = "Node";
+    private static final String DURATION_COLUMN_LABEL = "Duration (ms)";
+    private static final String ELAPSED_COLUMN_LABEL = "Elapsed (ms)";
+
+    private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+    private static final String DEFAULT_FIELD_PREAMBLE = " ";
+    private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+    private static final String DEFAULT_HEADER_PREAMBLE = " ";
+    private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+    private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+    private static final int MAX_COLUMN_WIDTH = Integer.MAX_VALUE;
+    private static final int MIN_COLUMN_WIDTH = 12;
+
+    private int limit;
+    private boolean sortByLongestDuration;
+
+    public ContextInflightCommand(String context, int limit, boolean 
sortByLongestDuration) {
+        super(context);
+        this.limit = limit;
+        this.sortByLongestDuration = sortByLongestDuration;
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
String contextName, PrintStream out, PrintStream err) throws Exception {
+        List<Map<String, Object>> inflight = 
camelController.browseInflightExchanges(contextName, limit, 
sortByLongestDuration);
+
+        final Map<String, Integer> columnWidths = 
computeColumnWidths(inflight);
+        final String headerFormat = buildFormatString(columnWidths, true);
+        final String rowFormat = buildFormatString(columnWidths, false);
+
+        if (inflight.size() > 0) {
+            out.println(String.format(headerFormat, EXCHANGE_COLUMN_LABEL, 
ROUTE_COLUMN_LABEL, NODE_COLUMN_LABEL, DURATION_COLUMN_LABEL, 
ELAPSED_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "----------", "-----", 
"----", "-------------", "------------"));
+            for (Map<String, Object> row : inflight) {
+                Object exchangeId = row.get("exchangeId");
+                Object routeId = row.get("routeId");
+                Object state = row.get("nodeId");
+                Object duration = row.get("duration");
+                Object elapsed = row.get("elapsed");
+                out.println(String.format(rowFormat, exchangeId, routeId, 
state, safeNull(duration), safeNull(elapsed)));
+            }
+        }
+
+        return null;
+    }
+
+    private Map<String, Integer> computeColumnWidths(final 
Iterable<Map<String, Object>> inflight) throws Exception {
+        if (inflight == null) {
+            throw new IllegalArgumentException("Unable to determine column 
widths from null Iterable<Inflight>");
+        } else {
+            int maxExchangeLen = 0;
+            int maxRouteLen = 0;
+            int maxNodeLen = 0;
+            int maxDurationLen = 0;
+            int maxElapsedLen = 0;
+
+            for (Map<String, Object> row : inflight) {
+                final String exchangeId = safeNull(row.get("exchangeId"));
+                maxExchangeLen = java.lang.Math.max(maxExchangeLen, exchangeId 
== null ? 0 : exchangeId.length());
+
+                final String routeId = safeNull(row.get("routeId"));
+                maxRouteLen = java.lang.Math.max(maxRouteLen, routeId == null 
? 0 : routeId.length());
+
+                final String nodeId = safeNull(row.get("nodeId"));
+                maxNodeLen = java.lang.Math.max(maxNodeLen, nodeId == null ? 0 
: nodeId.length());
+
+                final String duration = safeNull(row.get("duration"));
+                maxDurationLen = java.lang.Math.max(maxDurationLen, duration 
== null ? 0 : duration.length());
+
+                final String elapsed = safeNull(row.get("elapsed"));
+                maxElapsedLen = java.lang.Math.max(maxElapsedLen, elapsed == 
null ? 0 : elapsed.length());
+            }
+
+            final Map<String, Integer> retval = new Hashtable<String, 
Integer>(5);
+            retval.put(EXCHANGE_COLUMN_LABEL, maxExchangeLen);
+            retval.put(ROUTE_COLUMN_LABEL, maxRouteLen);
+            retval.put(NODE_COLUMN_LABEL, maxNodeLen);
+            retval.put(DURATION_COLUMN_LABEL, maxDurationLen);
+            retval.put(ELAPSED_COLUMN_LABEL, maxElapsedLen);
+
+            return retval;
+        }
+    }
+
+    private static String buildFormatString(final Map<String, Integer> 
columnWidths, final boolean isHeader) {
+        final String fieldPreamble;
+        final String fieldPostamble;
+        final int columnWidthIncrement;
+
+        if (isHeader) {
+            fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+            fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+        } else {
+            fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+            fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+        }
+        columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+        int exchangeLen = Math.min(columnWidths.get(EXCHANGE_COLUMN_LABEL) + 
columnWidthIncrement, MAX_COLUMN_WIDTH);
+        int routeLen = Math.min(columnWidths.get(ROUTE_COLUMN_LABEL) + 
columnWidthIncrement, MAX_COLUMN_WIDTH);
+        int nodeLen = Math.min(columnWidths.get(NODE_COLUMN_LABEL) + 
columnWidthIncrement, MAX_COLUMN_WIDTH);
+        int durationLen = Math.min(columnWidths.get(DURATION_COLUMN_LABEL) + 
columnWidthIncrement, MAX_COLUMN_WIDTH);
+        int elapsedLen = Math.min(columnWidths.get(ELAPSED_COLUMN_LABEL) + 
columnWidthIncrement, MAX_COLUMN_WIDTH);
+        exchangeLen = Math.max(MIN_COLUMN_WIDTH, exchangeLen);
+        routeLen = Math.max(MIN_COLUMN_WIDTH, routeLen);
+        nodeLen = Math.max(MIN_COLUMN_WIDTH, nodeLen);
+        durationLen = Math.max(13, durationLen);
+        elapsedLen = Math.max(MIN_COLUMN_WIDTH, elapsedLen);
+
+        final StringBuilder retval = new 
StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+        
retval.append(fieldPreamble).append("%-").append(exchangeLen).append('.').append(exchangeLen).append('s').append(fieldPostamble).append('
 ');
+        
retval.append(fieldPreamble).append("%-").append(routeLen).append('.').append(routeLen).append('s').append(fieldPostamble).append('
 ');
+        
retval.append(fieldPreamble).append("%-").append(nodeLen).append('.').append(nodeLen).append('s').append(fieldPostamble).append('
 ');
+        
retval.append(fieldPreamble).append("%").append(durationLen).append('.').append(durationLen).append('s').append(fieldPostamble).append('
 ');
+        
retval.append(fieldPreamble).append("%").append(elapsedLen).append('.').append(elapsedLen).append('s').append(fieldPostamble).append('
 ');
+
+        return retval.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
index ee8ecfb..4a31da49 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
@@ -228,12 +228,4 @@ public class ContextInfoCommand extends 
AbstractCamelCommand {
 
     }
 
-    private static String safeNull(Object value) {
-        if (value == null) {
-            return "";
-        } else {
-            return value.toString();
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
 
b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
index 9d95c38..0a44998 100644
--- 
a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
+++ 
b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
@@ -226,6 +226,39 @@ public class DefaultJolokiaCamelController extends 
AbstractCamelController imple
     }
 
     @Override
+    public List<Map<String, Object>> browseInflightExchanges(String 
camelContextName, int limit, boolean sortByLongestDuration) throws Exception {
+        if (jolokia == null) {
+            throw new IllegalStateException("Need to connect to remote jolokia 
first");
+        }
+
+        List<Map<String, Object>> answer = new ArrayList<Map<String, 
Object>>();
+
+        ObjectName found = lookupCamelContext(camelContextName);
+        if (found != null) {
+            String pattern = 
String.format("%s:context=%s,type=services,name=\"%s\"", found.getDomain(), 
found.getKeyProperty("context"), "DefaultInflightRepository");
+            ObjectName on = ObjectName.getInstance(pattern);
+            J4pExecResponse er = jolokia.execute(new J4pExecRequest(on, 
"browse(int,boolean)", limit, sortByLongestDuration));
+            if (er != null) {
+                JSONObject data = er.getValue();
+                for (Object obj : data.values()) {
+                    JSONObject data2 = (JSONObject) obj;
+                    JSONObject inflight = (JSONObject) 
data2.values().iterator().next();
+
+                    Map<String, Object> row = new LinkedHashMap<String, 
Object>();
+                    row.put("exchangeId", 
asString(inflight.get("exchangeId")));
+                    row.put("routeId", asString(inflight.get("routeIdId")));
+                    row.put("nodeId", asString(inflight.get("nodeId")));
+                    row.put("duration", asString(inflight.get("duration")));
+                    row.put("elapsed", asString(inflight.get("elapsed")));
+                    answer.add(row);
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    @Override
     public void startContext(String camelContextName) throws Exception {
         if (jolokia == null) {
             throw new IllegalStateException("Need to connect to remote jolokia 
first");

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CamelCommandSupport.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CamelCommandSupport.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CamelCommandSupport.java
index d419256..59204a8 100644
--- 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CamelCommandSupport.java
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CamelCommandSupport.java
@@ -30,12 +30,4 @@ public abstract class CamelCommandSupport extends 
OsgiCommandSupport {
         this.camelController = camelController;
     }
 
-    String safeNull(String s) {
-        if (s == null) {
-            return "";
-        } else {
-            return s;
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInflight.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInflight.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInflight.java
new file mode 100644
index 0000000..cba5ca3
--- /dev/null
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInflight.java
@@ -0,0 +1,43 @@
+/**
+ * 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.karaf.commands;
+
+import org.apache.camel.commands.ContextInflightCommand;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "camel", name = "context-inflight", description = "List 
inflight exchanges.")
+public class ContextInflight extends CamelCommandSupport {
+
+    @Argument(index = 0, name = "name", description = "The Camel context 
name", required = true, multiValued = false)
+    String name;
+
+    @Option(name = "--limit", aliases = "-l", description = "To limit the 
number of exchanges shown",
+            required = false, multiValued = false)
+    int limit = -1;
+
+    @Option(name = "--sort", aliases = "-s", description = "true = sort by 
longest duration, false = sort by exchange id",
+            required = false, multiValued = false, valueToShowInHelp = "false")
+    boolean sortByLongestDuration;
+
+    protected Object doExecute() throws Exception {
+        ContextInflightCommand command = new ContextInflightCommand(name, 
limit, sortByLongestDuration);
+        return command.execute(camelController, System.out, System.err);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f812a45e/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
 
b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
index ec77fb6..fc54ac8 100644
--- 
a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
+++ 
b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
@@ -69,6 +69,15 @@
         <null/>
       </completers>
     </command>
+    <command name="camel/context-inflight">
+      <action class="org.apache.camel.karaf.commands.ContextInflight">
+        <property name="camelController" ref="camelController"/>
+      </action>
+      <completers>
+        <ref component-id="camelContextCompleter"/>
+        <null/>
+      </completers>
+    </command>
     <command name="camel/route-list">
       <action class="org.apache.camel.karaf.commands.RouteList">
         <property name="camelController" ref="camelController"/>

Reply via email to