This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch ra in repository https://gitbox.apache.org/repos/asf/camel.git
commit b24ab58dd7b108b2e6b944e4ae085330d8e86a53 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon May 27 12:12:43 2024 +0200 CAMEL-20798: Add RemoteAddress to endpoints so they can tell the url/hostname etc for the system it connects. This is needed for better monitoring, tracing and management. Add this information into camel-tracer as tags. --- .../camel/component/activemq/ActiveMQEndpoint.java | 5 + .../platform/http/PlatformHttpEndpoint.java | 5 + ...onAddress.java => EndpointServiceLocation.java} | 22 ++-- .../org/apache/camel/dev-console/protocol.json | 15 +++ .../services/org/apache/camel/dev-console/protocol | 2 + .../org/apache/camel/dev-consoles.properties | 2 +- .../camel/impl/console/ConsumerDevConsole.java | 3 - .../camel/impl/console/EndpointDevConsole.java | 10 -- .../camel/impl/console/ProtocolDevConsole.java | 133 +++++++++++++++++++++ .../api/management/mbean/ManagedEndpointMBean.java | 9 +- .../camel/management/mbean/ManagedEndpoint.java | 22 ++-- .../jbang/core/commands/process/ListAddress.java | 1 + .../jbang/core/commands/process/ListService.java | 2 + 13 files changed, 200 insertions(+), 31 deletions(-) diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java index 0f2de7b346e..12902718dc1 100644 --- a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java @@ -72,6 +72,11 @@ public class ActiveMQEndpoint extends JmsEndpoint implements EndpointLocationAdd return url; } + @Override + public String getServiceProtocol() { + return "jms"; + } + @Override public Map<String, String> getAddressMetadata() { String un = null; diff --git a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java index 7ff1eed4f92..e5bc1be80e5 100644 --- a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java +++ b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpEndpoint.java @@ -107,6 +107,11 @@ public class PlatformHttpEndpoint extends DefaultEndpoint return server; } + @Override + public String getServiceProtocol() { + return "http"; + } + @Override public Producer createProducer() throws Exception { throw new UnsupportedOperationException("Producer is not supported"); diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/EndpointLocationAddress.java b/core/camel-api/src/main/java/org/apache/camel/spi/EndpointServiceLocation.java similarity index 67% rename from core/camel-api/src/main/java/org/apache/camel/spi/EndpointLocationAddress.java rename to core/camel-api/src/main/java/org/apache/camel/spi/EndpointServiceLocation.java index e2eafe39113..86a3a119398 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/EndpointLocationAddress.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/EndpointServiceLocation.java @@ -19,29 +19,37 @@ package org.apache.camel.spi; import java.util.Map; /** - * Used for getting information about (hosted or external) service addresses used for connecting to a remote system such - * as message brokers, databases, or cloud services. + * Used for getting information about location to (hosted or external) network services. + * + * An external service such as message brokers, databases, or cloud services. * * Hosted services are running inside this Camel application such as with embedded HTTP server for Rest DSL, or TCP * networking with netty etc. + * + * @see org.apache.camel.Endpoint */ -public interface EndpointLocationAddress { +public interface EndpointServiceLocation { /** - * Gets the remote address such as URL or hostname + * Gets the remote address such as URL, hostname, or connection-string that are component specific * * @return the address or null if no address can be determined. */ - String getAddress(); + String getServiceUrl(); + + /** + * Get the protocol the service is using such as http, amqp, tcp. + */ + String getServiceProtocol(); /** - * Optional additional metadata that is relevant to the address as key value pairs. Notice that the metadata is not + * Optional metadata that is relevant to the service as key value pairs. Notice that the metadata is not * supposed to contain sensitive security details such as access token, api keys, or passwords. Only share * information that can be safely accessed and written to logs. * * @return optional metadata or null if no data */ - default Map<String, String> getAddressMetadata() { + default Map<String, String> getServiceMetadata() { return null; } } diff --git a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/protocol.json b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/protocol.json new file mode 100644 index 00000000000..e7a34a208cc --- /dev/null +++ b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/protocol.json @@ -0,0 +1,15 @@ +{ + "console": { + "kind": "console", + "group": "camel", + "name": "protocol", + "title": "Protocols", + "description": "Protocols used for network communication with clients", + "deprecated": false, + "javaType": "org.apache.camel.impl.console.ProtocolDevConsole", + "groupId": "org.apache.camel", + "artifactId": "camel-console", + "version": "4.7.0-SNAPSHOT" + } +} + diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/protocol b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/protocol new file mode 100644 index 00000000000..0ba65348685 --- /dev/null +++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/protocol @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.impl.console.ProtocolDevConsole diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties index c65dacbcf02..923478dde7d 100644 --- a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties +++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties @@ -1,5 +1,5 @@ # Generated by camel build tools - do NOT edit this file! -dev-consoles=bean blocked circuit-breaker consumer context debug endpoint event gc health inflight java-security jvm log memory properties reload route route-controller route-dump source startup-recorder thread top trace transformers type-converters variables +dev-consoles=bean blocked circuit-breaker consumer context debug endpoint event gc health inflight java-security jvm log memory properties protocol reload route route-controller route-dump source startup-recorder thread top trace transformers type-converters variables groupId=org.apache.camel artifactId=camel-console version=4.7.0-SNAPSHOT diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java index 91004eaf753..858edf525a8 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java @@ -63,7 +63,6 @@ public class ConsumerDevConsole extends AbstractDevConsole { sb.append(String.format("\n Uri: %s", mc.getEndpointUri())); sb.append(String.format("\n State: %s", mc.getState())); sb.append(String.format("\n Class: %s", mc.getServiceType())); - sb.append(String.format("\n Hosted Service: %b", mc.isHostedService())); sb.append(String.format("\n Inflight: %d", inflight)); if (mcc instanceof ManagedSchedulePollConsumerMBean mpc) { sb.append(String.format("\n Polling: %s", mpc.isPolling())); @@ -151,7 +150,6 @@ public class ConsumerDevConsole extends AbstractDevConsole { jo.put("uri", mc.getEndpointUri()); jo.put("state", mc.getState()); jo.put("class", mc.getServiceType()); - jo.put("hostedService", mc.isHostedService()); jo.put("inflight", inflight); jo.put("scheduled", false); if (mcc instanceof ManagedSchedulePollConsumerMBean mpc) { @@ -212,7 +210,6 @@ public class ConsumerDevConsole extends AbstractDevConsole { // ignore } } - final JsonObject stats = toJsonObject(mr); jo.put("statistics", stats); diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java index 67cf79047b6..24779c5d724 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/EndpointDevConsole.java @@ -24,7 +24,6 @@ import java.util.Optional; import org.apache.camel.Endpoint; import org.apache.camel.spi.EndpointRegistry; -import org.apache.camel.spi.EndpointLocationAddress; import org.apache.camel.spi.RuntimeEndpointRegistry; import org.apache.camel.spi.annotations.DevConsole; import org.apache.camel.support.console.AbstractDevConsole; @@ -106,15 +105,6 @@ public class EndpointDevConsole extends AbstractDevConsole { jo.put("hits", st.getHits()); jo.put("routeId", st.getRouteId()); } - if (e instanceof EndpointLocationAddress raa) { - JsonObject ro = new JsonObject(); - ro.put("address", raa.getAddress()); - var d = raa.getAddressMetadata(); - if (d != null) { - ro.putAll(d); - } - jo.put("location", ro); - } list.add(jo); } diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/ProtocolDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProtocolDevConsole.java new file mode 100644 index 00000000000..cd8abb50039 --- /dev/null +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProtocolDevConsole.java @@ -0,0 +1,133 @@ +/* + * 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.impl.console; + +import org.apache.camel.Consumer; +import org.apache.camel.Endpoint; +import org.apache.camel.Route; +import org.apache.camel.spi.EndpointServiceLocation; +import org.apache.camel.spi.EndpointRegistry; +import org.apache.camel.spi.RuntimeEndpointRegistry; +import org.apache.camel.spi.annotations.DevConsole; +import org.apache.camel.support.DefaultConsumer; +import org.apache.camel.support.console.AbstractDevConsole; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@DevConsole(name = "protocol", displayName = "Protocols", description = "Protocols used for network communication with clients") +public class ProtocolDevConsole extends AbstractDevConsole { + + public ProtocolDevConsole() { + super("camel", "protocol", "Protocols", "Protocols used for network communication with clients"); + } + + @Override + protected String doCallText(Map<String, Object> options) { + StringBuilder sb = new StringBuilder(); + + // runtime registry is optional but if enabled we have additional statistics to use in output + List<RuntimeEndpointRegistry.Statistic> stats = null; + RuntimeEndpointRegistry runtimeReg = getCamelContext().getRuntimeEndpointRegistry(); + if (runtimeReg != null) { + stats = runtimeReg.getEndpointStatistics(); + } + EndpointRegistry reg = getCamelContext().getEndpointRegistry(); + + // find all consumers (IN) direction + for (Route route : getCamelContext().getRoutes()) { + Consumer consumer = route.getConsumer(); + Endpoint endpoint = consumer.getEndpoint(); + if (endpoint instanceof EndpointServiceLocation raa) { + String component = endpoint.getComponent().getDefaultName(); + boolean hosted = false; + if (consumer instanceof DefaultConsumer dc) { + hosted = dc.isHostedService(); + } + String adr = raa.getServiceUrl(); + String protocol = raa.getServiceProtocol(); + if (adr != null) { + var stat = findStats(stats, endpoint.getEndpointUri(), "in"); + var uri = endpoint.toString(); + printLine(sb, component, stat, "in", hosted, protocol, adr, uri); + } + } + } + + // find all endpoint (OUT) direction + for (Endpoint endpoint : reg.getReadOnlyValues()) { + if (endpoint instanceof EndpointServiceLocation raa) { + String component = endpoint.getComponent().getDefaultName(); + boolean hosted = false; + String adr = raa.getServiceUrl(); + String protocol = raa.getServiceProtocol(); + if (adr != null) { + var stat = findStats(stats, endpoint.getEndpointUri(), "in"); + // skip IN as already found via consumer (platform-http is only IN) + boolean skip = "platform-http".equals(component) || stat.isPresent() && "in".equals(stat.get().getDirection()); + if (!skip) { + var uri = endpoint.toString(); + printLine(sb, component, stat, "in", hosted, protocol, adr, uri); + } + } + } + } + + sb.append("\n"); + + return sb.toString(); + } + + private static void printLine(StringBuilder sb, String component, Optional<RuntimeEndpointRegistry.Statistic> stat, + String dir, boolean hosted, String protocol, String adr, String uri) { + + long total = 0; + if (stat.isPresent()) { + dir = stat.get().getDirection(); + total = stat.get().getHits(); + } + + if (!sb.isEmpty()) { + sb.append("\n"); + } + sb.append(String.format("\n Component: %s", component)); + sb.append(String.format("\n Direction: %s", dir)); + sb.append(String.format("\n Hosted Service: %b", hosted)); + sb.append(String.format("\n Usage: %d", total)); + sb.append(String.format("\n Protocol: %s", protocol)); + sb.append(String.format("\n Service: %s", adr)); + sb.append(String.format("\n Endpoint Uri: %s", uri)); + } + + @Override + protected Map<String, Object> doCallJson(Map<String, Object> options) { + // TODO: + return null; + } + + private static Optional<RuntimeEndpointRegistry.Statistic> findStats( + List<RuntimeEndpointRegistry.Statistic> stats, String uri, String direction) { + if (stats == null) { + return Optional.empty(); + } + return stats.stream() + .filter(s -> uri.equals(s.getUri()) && (direction == null || s.getDirection().equals(direction))) + .findFirst(); + } + +} diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEndpointMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEndpointMBean.java index e3cd0504ad8..79d9956d861 100644 --- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEndpointMBean.java +++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEndpointMBean.java @@ -40,10 +40,13 @@ public interface ManagedEndpointMBean { @ManagedAttribute(description = "Endpoint State") String getState(); - @ManagedAttribute(description = "Address (such as URL or hostname) this endpoint is connecting (only available for some components)") - String getEndpointLocationAddress(); + @ManagedAttribute(description = "Url used for network connecting to service (only available for some components)") + String getServiceLocationUrl(); + + @ManagedAttribute(description = "Protocol used for service connecting (only available for some components)") + String getServiceLocationProtocol(); @ManagedAttribute(description = "Additional metadata this endpoint is used for connecting (only available for some components)") - Map<String, String> getEndpointLocationAddressMetadata(); + Map<String, String> getServiceLocationMetadata(); } diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEndpoint.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEndpoint.java index 200d9a5066c..df4510213b0 100644 --- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEndpoint.java +++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEndpoint.java @@ -24,7 +24,7 @@ import org.apache.camel.StatefulService; import org.apache.camel.api.management.ManagedInstance; import org.apache.camel.api.management.ManagedResource; import org.apache.camel.api.management.mbean.ManagedEndpointMBean; -import org.apache.camel.spi.EndpointLocationAddress; +import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.ManagementStrategy; @ManagedResource(description = "Managed Endpoint") @@ -81,17 +81,25 @@ public class ManagedEndpoint implements ManagedInstance, ManagedEndpointMBean { } @Override - public String getEndpointLocationAddress() { - if (endpoint instanceof EndpointLocationAddress raa) { - return raa.getAddress(); + public String getServiceLocationUrl() { + if (endpoint instanceof EndpointServiceLocation raa) { + return raa.getServiceUrl(); } return null; } @Override - public Map<String, String> getEndpointLocationAddressMetadata() { - if (endpoint instanceof EndpointLocationAddress raa) { - return raa.getAddressMetadata(); + public String getServiceLocationProtocol() { + if (endpoint instanceof EndpointServiceLocation raa) { + return raa.getServiceProtocol(); + } + return null; + } + + @Override + public Map<String, String> getServiceLocationMetadata() { + if (endpoint instanceof EndpointServiceLocation raa) { + return raa.getServiceMetadata(); } return null; } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListAddress.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListAddress.java index 0058e83e297..d0680e9760e 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListAddress.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListAddress.java @@ -36,6 +36,7 @@ import picocli.CommandLine; import picocli.CommandLine.Command; @Command(name = "address", description = "Get usage of Camel service addresses (hosted and external)", sortOptions = false) +@Deprecated // TODO: protocol public class ListAddress extends ProcessWatchCommand { @CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1") diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java index 1e9879f9d31..d5696444ca5 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java @@ -33,6 +33,8 @@ import org.apache.camel.util.json.JsonObject; import picocli.CommandLine; import picocli.CommandLine.Command; + +// TODO: protocol @Command(name = "service", description = "Get services of Camel integrations", sortOptions = false) public class ListService extends ProcessWatchCommand {