This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 14b7eb4441bb1a55f5c61c0f609fe7c00714c24f Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Mon Dec 5 14:08:49 2022 +0100 CAMEL-18743 - camel-jbang - Command to see only if everything is okay or there has been a failure Signed-off-by: Andrea Cosentino <anco...@gmail.com> --- .../dsl/jbang/core/commands/CamelJBangMain.java | 23 +--- .../jbang/core/commands/process/CamelCount.java | 138 +++++++++++++++++++++ 2 files changed, 140 insertions(+), 21 deletions(-) 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 00d7b53de56..cb74f20ccca 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 @@ -38,27 +38,7 @@ import org.apache.camel.dsl.jbang.core.commands.catalog.CatalogDoc; import org.apache.camel.dsl.jbang.core.commands.catalog.CatalogKamelet; 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; -import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteTop; -import org.apache.camel.dsl.jbang.core.commands.process.CamelStatus; -import org.apache.camel.dsl.jbang.core.commands.process.CamelTop; -import org.apache.camel.dsl.jbang.core.commands.process.Hawtio; -import org.apache.camel.dsl.jbang.core.commands.process.Jolokia; -import org.apache.camel.dsl.jbang.core.commands.process.ListBlocked; -import org.apache.camel.dsl.jbang.core.commands.process.ListCircuitBreaker; -import org.apache.camel.dsl.jbang.core.commands.process.ListEvent; -import org.apache.camel.dsl.jbang.core.commands.process.ListHealth; -import org.apache.camel.dsl.jbang.core.commands.process.ListInflight; -import org.apache.camel.dsl.jbang.core.commands.process.ListMetric; -import org.apache.camel.dsl.jbang.core.commands.process.ListProcess; -import org.apache.camel.dsl.jbang.core.commands.process.ListService; -import org.apache.camel.dsl.jbang.core.commands.process.ListVault; -import org.apache.camel.dsl.jbang.core.commands.process.StopProcess; +import org.apache.camel.dsl.jbang.core.commands.process.*; import picocli.CommandLine; import picocli.CommandLine.Command; @@ -88,6 +68,7 @@ public class CamelJBangMain implements Callable<Integer> { .addSubcommand("service", new CommandLine(new ListService(main))) .addSubcommand("source", new CommandLine(new CamelSourceAction(main))) .addSubcommand("vault", new CommandLine(new ListVault(main)))) + .addSubcommand("count", new CommandLine(new CamelCount(main))) .addSubcommand("top", new CommandLine(new CamelTop(main)) .addSubcommand("context", new CommandLine(new CamelContextTop(main))) .addSubcommand("route", new CommandLine(new CamelRouteTop(main))) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java new file mode 100644 index 00000000000..86c20f0f788 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java @@ -0,0 +1,138 @@ +/* + * 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 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.dsl.jbang.core.common.ProcessHelper; +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; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@Command(name = "count", + description = "Get total and failed exchanges for a running integration") +public class CamelCount 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 or age", defaultValue = "pid") + String sort; + + public CamelCount(CamelJBangMain main) { + super(main); + } + + @Override + public Integer call() throws Exception { + List<Row> rows = new ArrayList<>(); + + List<Long> pids = findPids(name); + ProcessHandle.allProcesses() + .filter(ph -> pids.contains(ph.pid())) + .forEach(ph -> { + JsonObject root = loadStatus(ph.pid()); + // there must be a status file for the running Camel integration + if (root != null) { + Row row = new Row(); + JsonObject context = (JsonObject) root.get("context"); + if (context == null) { + return; + } + row.name = context.getString("name"); + if ("CamelJBang".equals(row.name)) { + row.name = ProcessHelper.extractName(root, ph); + } + row.pid = "" + ph.pid(); + row.age = TimeUtils.printSince(extractSince(ph)); + Map<String, ?> stats = context.getMap("statistics"); + if (stats != null) { + row.total = stats.get("exchangesTotal").toString(); + row.failed = stats.get("exchangesFailed").toString(); + } + rows.add(row); + } + }); + + // sort rows + rows.sort(this::sortRow); + + if (!rows.isEmpty()) { + 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("TOTAL").with(r -> r.total), + new Column().header("FAIL").with(r -> r.failed)))); + } + + return 0; + } + + private String extractPlatform(ProcessHandle ph, JsonObject runtime) { + String answer = runtime != null ? runtime.getString("platform") : null; + if ("Camel".equals(answer)) { + // generic camel, we need to check if we run in JBang + String cl = ph.info().commandLine().orElse(""); + if (cl.contains("main.CamelJBang run")) { + answer = "JBang"; + } + } + return answer; + } + + 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; + default: + return 0; + } + } + + private static class Row { + String pid; + String name; + String age; + long uptime; + String total; + String failed; + } + +}