This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit a85fc5ef22867e8c9ec7ac9270c4ce4caa642742 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Sep 22 10:58:16 2022 +0200 camel-jbang - Add get endpoint command --- .../camel/dev-console/{endpoints => endpoint} | 2 +- ...intsDevConsole.java => EndpointDevConsole.java} | 13 +- .../camel/cli/connector/LocalCliConnector.java | 10 +- .../dsl/jbang/core/commands/CamelJBangMain.java | 2 + .../core/commands/action/CamelThreadDump.java | 2 +- .../core/commands/process/CamelContextStatus.java | 8 +- .../core/commands/process/CamelContextTop.java | 2 +- .../core/commands/process/CamelEndpointStatus.java | 171 +++++++++++++++++++++ .../commands/process/CamelProcessorStatus.java | 2 +- .../core/commands/process/CamelRouteStatus.java | 2 +- .../jbang/core/commands/process/ListProcess.java | 2 +- .../dsl/jbang/core/commands/process/ListVault.java | 2 +- 12 files changed, 199 insertions(+), 19 deletions(-) diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoints b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoint similarity index 50% rename from core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoints rename to core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoint index 40c569b1839..3fe0ba7af74 100644 --- a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoints +++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/endpoint @@ -1,2 +1,2 @@ # Generated by camel build tools - do NOT edit this file! -class=org.apache.camel.impl.console.EndpointsDevConsole +class=org.apache.camel.impl.console.EndpointDevConsole diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointsDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java similarity index 93% rename from core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointsDevConsole.java rename to core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java index ce2cfa27410..07e873e3f4c 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointsDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java @@ -29,11 +29,11 @@ import org.apache.camel.spi.RuntimeEndpointRegistry; import org.apache.camel.spi.annotations.DevConsole; import org.apache.camel.util.json.JsonObject; -@DevConsole("endpoints") -public class EndpointsDevConsole extends AbstractDevConsole { +@DevConsole("endpoint") +public class EndpointDevConsole extends AbstractDevConsole { - public EndpointsDevConsole() { - super("camel", "endpoints", "Endpoints", "Endpoint Registry information"); + public EndpointDevConsole() { + super("camel", "endpoint", "Endpoints", "Endpoint Registry information"); } @Override @@ -88,7 +88,7 @@ public class EndpointsDevConsole extends AbstractDevConsole { Collection<Endpoint> col = reg.getReadOnlyValues(); for (Endpoint e : col) { JsonObject jo = new JsonObject(); - jo.put("uri", jo.toString()); + jo.put("uri", e.toString()); var stat = findStats(stats, e.getEndpointUri()); if (stat.isPresent()) { var st = stat.get(); @@ -102,7 +102,8 @@ public class EndpointsDevConsole extends AbstractDevConsole { return root; } - private static Optional<RuntimeEndpointRegistry.Statistic> findStats(List<RuntimeEndpointRegistry.Statistic> stats, String uri) { + private static Optional<RuntimeEndpointRegistry.Statistic> findStats( + List<RuntimeEndpointRegistry.Statistic> stats, String uri) { if (stats == null) { return Optional.empty(); } diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java index dd2dcaf7701..627fdc81a44 100644 --- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java +++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java @@ -330,10 +330,16 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C } } DevConsole dc3 = camelContext.adapt(ExtendedCamelContext.class) - .getDevConsoleResolver().resolveDevConsole("health"); + .getDevConsoleResolver().resolveDevConsole("endpoint"); if (dc3 != null) { + JsonObject json = (JsonObject) dc3.call(DevConsole.MediaType.JSON); + root.put("endpoints", json); + } + DevConsole dc4 = camelContext.adapt(ExtendedCamelContext.class) + .getDevConsoleResolver().resolveDevConsole("health"); + if (dc4 != null) { // include full details in health checks - JsonObject json = (JsonObject) dc3.call(DevConsole.MediaType.JSON, Map.of("exposureLevel", "full")); + JsonObject json = (JsonObject) dc4.call(DevConsole.MediaType.JSON, Map.of("exposureLevel", "full")); root.put("healthChecks", json); } // various details diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java index abf0ed8bf09..4f56cdc1f64 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java @@ -37,6 +37,7 @@ import org.apache.camel.dsl.jbang.core.commands.catalog.CatalogLanguage; import org.apache.camel.dsl.jbang.core.commands.catalog.CatalogOther; import org.apache.camel.dsl.jbang.core.commands.process.CamelContextStatus; import org.apache.camel.dsl.jbang.core.commands.process.CamelContextTop; +import org.apache.camel.dsl.jbang.core.commands.process.CamelEndpointStatus; import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorStatus; import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorTop; import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteStatus; @@ -66,6 +67,7 @@ public class CamelJBangMain implements Callable<Integer> { .addSubcommand("context", new CommandLine(new CamelContextStatus(main))) .addSubcommand("route", new CommandLine(new CamelRouteStatus(main))) .addSubcommand("processor", new CommandLine(new CamelProcessorStatus(main))) + .addSubcommand("endpoint", new CommandLine(new CamelEndpointStatus(main))) .addSubcommand("vault", new CommandLine(new ListVault(main)))) .addSubcommand("top", new CommandLine(new CamelTop(main)) .addSubcommand("context", new CommandLine(new CamelContextTop(main))) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java index b8a838e72e9..bbfa0534539 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java @@ -184,7 +184,7 @@ public class CamelThreadDump extends ActionBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "id": return Long.compare(o1.id, o2.id) * negate; case "name": diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java index 47b94ea9c86..f266b9619e3 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java @@ -66,7 +66,7 @@ public class CamelContextStatus extends ProcessBaseCommand { } row.pid = "" + ph.pid(); row.uptime = extractSince(ph); - row.ago = TimeUtils.printSince(row.uptime); + row.age = TimeUtils.printSince(row.uptime); JsonObject runtime = (JsonObject) root.get("runtime"); row.platform = extractPlatform(ph, runtime); row.platformVersion = runtime != null ? runtime.getString("platformVersion") : null; @@ -131,7 +131,7 @@ public class CamelContextStatus extends ProcessBaseCommand { .with(r -> extractState(r.state)), new Column().header("RELOAD").headerAlign(HorizontalAlign.CENTER) .with(r -> r.reloaded), - new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago), + new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.age), new Column().header("ROUTE").with(this::getRoutes), new Column().header("MSG/S").with(this::getThroughput), new Column().header("TOTAL").with(r -> r.total), @@ -162,7 +162,7 @@ public class CamelContextStatus extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name": @@ -212,7 +212,7 @@ public class CamelContextStatus extends ProcessBaseCommand { int routeTotal; int state; String reloaded; - String ago; + String age; long uptime; String throughput; String total; diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java index 675c7664828..c08e3b66d8d 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java @@ -164,7 +164,7 @@ public class CamelContextTop extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name": diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java new file mode 100644 index 00000000000..413b8133814 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java @@ -0,0 +1,171 @@ +/* + * 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.dsl.jbang.core.commands.process; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.github.freva.asciitable.AsciiTable; +import com.github.freva.asciitable.Column; +import com.github.freva.asciitable.HorizontalAlign; +import com.github.freva.asciitable.OverflowBehaviour; +import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; +import org.apache.camel.support.PatternHelper; +import org.apache.camel.util.TimeUtils; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; +import picocli.CommandLine; +import picocli.CommandLine.Command; + +@Command(name = "endpoint", aliases = { "endpoint", "endpoints" }, description = "Get usage of Camel endpoints") +public class CamelEndpointStatus extends ProcessBaseCommand { + + @CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1") + String name = "*"; + + @CommandLine.Option(names = { "--sort" }, + description = "Sort by pid, name, age or total", defaultValue = "pid") + String sort; + + @CommandLine.Option(names = { "--limit" }, + description = "Filter endpoints by limiting to the given number of rows") + int limit; + + @CommandLine.Option(names = { "--filter" }, + description = "Filter endpoints by URI") + String filter; + + @CommandLine.Option(names = { "--filter-direction" }, + description = "Filter by direction (in or out)") + String filterDirection; + + @CommandLine.Option(names = { "--filter-total" }, + description = "Filter endpoints that must be higher than the given usage") + long filterTotal; + + public CamelEndpointStatus(CamelJBangMain main) { + super(main); + } + + @Override + public Integer call() throws Exception { + List<Row> rows = new ArrayList<>(); + + // make it easier to filter + if (filter != null && !filter.endsWith("*")) { + filter += "*"; + } + + List<Long> pids = findPids(name); + ProcessHandle.allProcesses() + .filter(ph -> pids.contains(ph.pid())) + .forEach(ph -> { + JsonObject root = loadStatus(ph.pid()); + if (root != null) { + JsonObject context = (JsonObject) root.get("context"); + JsonObject jo = (JsonObject) root.get("endpoints"); + if (jo != null) { + JsonArray array = (JsonArray) jo.get("endpoints"); + for (int i = 0; i < array.size(); i++) { + JsonObject o = (JsonObject) array.get(i); + Row row = new Row(); + row.name = context.getString("name"); + if ("CamelJBang".equals(row.name)) { + row.name = extractName(root, ph); + } + row.pid = "" + ph.pid(); + row.endpoint = o.getString("uri"); + row.direction = o.getString("direction"); + row.total = o.getString("hits"); + row.uptime = extractSince(ph); + row.age = TimeUtils.printSince(row.uptime); + boolean add = true; + if (filterTotal > 0 && (row.total == null || Long.parseLong(row.total) < filterTotal)) { + add = false; + } + if (filterDirection != null && !filterDirection.equals(row.direction)) { + add = false; + } + if (filter != null && !PatternHelper.matchPattern(row.endpoint, filter)) { + add = false; + } + if (limit > 0 && rows.size() >= limit) { + add = false; + } + if (add) { + rows.add(row); + } + } + } + } + }); + + // sort rows + rows.sort(this::sortRow); + + if (!rows.isEmpty()) { + printTable(rows); + } + + return 0; + } + + protected void printTable(List<Row> rows) { + System.out.println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( + new Column().header("PID").headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), + new Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(30, OverflowBehaviour.ELLIPSIS_RIGHT) + .with(r -> r.name), + new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.age), + new Column().header("DIR").with(r -> r.direction), + new Column().header("URI").dataAlign(HorizontalAlign.LEFT).maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) + .with(r -> r.endpoint), + new Column().header("TOTAL").with(r -> r.total)))); + } + + protected int sortRow(Row o1, Row o2) { + String s = sort; + int negate = 1; + if (s.startsWith("-")) { + s = s.substring(1); + negate = -1; + } + switch (s) { + case "pid": + return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; + case "name": + return o1.name.compareToIgnoreCase(o2.name) * negate; + case "age": + return Long.compare(o1.uptime, o2.uptime) * negate; + case "total": + return Long.compare(Long.parseLong(o1.total), Long.parseLong(o2.total)) * negate; + default: + return 0; + } + } + + static class Row { + String pid; + String name; + long uptime; + String age; + String endpoint; + String direction; + String total; + } + +} diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java index d5073c16a2d..3c92a47a24b 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java @@ -206,7 +206,7 @@ public class CamelProcessorStatus extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name": diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java index b5f00d9ea8f..cd625ef63a5 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java @@ -183,7 +183,7 @@ public class CamelRouteStatus extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name": diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java index 3730aab9cfc..c5346912b82 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java @@ -96,7 +96,7 @@ public class ListProcess extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name": diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java index 548c77661e7..aee406651f5 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java @@ -128,7 +128,7 @@ public class ListVault extends ProcessBaseCommand { s = s.substring(1); negate = -1; } - switch (sort) { + switch (s) { case "pid": return Long.compare(Long.parseLong(o1.pid), Long.parseLong(o2.pid)) * negate; case "name":
