This is an automated email from the ASF dual-hosted git repository. squakez pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 340c6bf44b08e17b18e67443d0b45825fae5dd08 Author: Pasquale Congiusti <[email protected]> AuthorDate: Mon May 25 09:51:49 2026 +0200 feat(components): support telemetry include patterns Closes CAMEL-23433 --- .../src/main/docs/micrometer-observability.adoc | 3 +- .../src/main/docs/opentelemetry2.adoc | 3 +- .../src/main/docs/telemetry-dev.adoc | 3 +- .../camel-telemetry/src/main/docs/telemetry.adoc | 3 +- .../TraceProcessorsInterceptStrategy.java | 4 +- .../java/org/apache/camel/telemetry/Tracer.java | 55 +++++++-- .../camel/telemetry/TracerExcludePatternsTest.java | 133 ++++++++++++++++++++ .../camel/telemetry/TracerIncludePatternsTest.java | 135 +++++++++++++++++++++ .../apache/camel/telemetry/TracerMatchTest.java | 107 ++++++++++++++++ 9 files changed, 428 insertions(+), 18 deletions(-) diff --git a/components/camel-micrometer-observability/src/main/docs/micrometer-observability.adoc b/components/camel-micrometer-observability/src/main/docs/micrometer-observability.adoc index 45bf7e99be2b..59b4f3957ce5 100644 --- a/components/camel-micrometer-observability/src/main/docs/micrometer-observability.adoc +++ b/components/camel-micrometer-observability/src/main/docs/micrometer-observability.adoc @@ -31,7 +31,8 @@ The configuration properties for the component are: |`enabled`| false | Turn the tracing on/off. |`traceProcessors`| false | Trace inner custom processors (i.e., any `process` configured in the route). |`disableCoreProcessors`| false | Disable any inner core processors (any core DSL processor provided in the route, for example `bean`, `log`, ...). -|`excludePatterns` | | Sets exclude pattern that will disable tracing for those spans that matches the pattern. The variable is a comma separated values of filters to execute (eg, `log*,direct*,setBody*`, ...) +| `excludePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to exclude from tracing. Spans matching these patterns will be disabled. If nothing is specified, no processors are excluded by default. +| `includePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to explicitly include in a trace. Spans matching these patterns will be enabled. If nothing is specified, all processors are included by default. |`traceHeadersInclusion`| false | Add the generated telemetry `CAMEL_TRACE_ID` and `CAMEL_SPAN_ID` Exchange headers. |======================================================================= diff --git a/components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc b/components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc index 30131ac05bc4..ef42bad2eaa4 100644 --- a/components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc +++ b/components/camel-opentelemetry2/src/main/docs/opentelemetry2.adoc @@ -27,7 +27,8 @@ The configuration properties for the OpenTelemetry2 tracer are: |`enabled`| false | Turn the tracing on/off. |`traceProcessors`| false | Trace inner custom processors (i.e., any `process` configured in the route). When disabled, custom processors are not visible from the OpenTelemetry perspective and have no active span or context. |`disableCoreProcessors`| false | Disable any inner core processors (any core DSL processor provided in the route, for example `bean`, `log`, ...). -| `excludePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to exclude from tracing. Spans matching these patterns will be disabled. +| `excludePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to exclude from tracing. Spans matching these patterns will be disabled. If nothing is specified, no processors are excluded by default. +| `includePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to explicitly include in a trace. Spans matching these patterns will be enabled. If nothing is specified, all processors are included by default. | `traceHeadersInclusion`| `false` | If set to `true`, adds the generated telemetry `CAMEL_TRACE_ID` and `CAMEL_SPAN_ID` Exchange headers. |======================================================================= diff --git a/components/camel-telemetry-dev/src/main/docs/telemetry-dev.adoc b/components/camel-telemetry-dev/src/main/docs/telemetry-dev.adoc index 2eba44a3a767..f0292511912a 100644 --- a/components/camel-telemetry-dev/src/main/docs/telemetry-dev.adoc +++ b/components/camel-telemetry-dev/src/main/docs/telemetry-dev.adoc @@ -30,7 +30,8 @@ The configuration properties for the Telemetry component are: |`traceFormat`| default | The format used to trace in the log (default, tree, json). |`traceProcessors`| false | Trace inner custom processors (i.e., any `process` configured in the route). |`disableCoreProcessors`| false | Disable any inner core processors (any core DSL processor provided in the route, for example `bean`, `log`, ...). -|`excludePatterns` | | Sets exclude pattern that will disable tracing for those spans that matches the pattern. The variable is a comma separated values of filters to execute (eg, `log*,direct*,setBody*`, ...) +| `excludePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to exclude from tracing. Spans matching these patterns will be disabled. If nothing is specified, no processors are excluded by default. +| `includePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to explicitly include in a trace. Spans matching these patterns will be enabled. If nothing is specified, all processors are included by default. |`traceHeadersInclusion`| false | Add the generated telemetry `CAMEL_TRACE_ID` and `CAMEL_SPAN_ID` Exchange headers. |======================================================================= diff --git a/components/camel-telemetry/src/main/docs/telemetry.adoc b/components/camel-telemetry/src/main/docs/telemetry.adoc index 9d09d5fafbf3..72c3c8a43231 100644 --- a/components/camel-telemetry/src/main/docs/telemetry.adoc +++ b/components/camel-telemetry/src/main/docs/telemetry.adoc @@ -28,7 +28,8 @@ The configuration properties for the Telemetry component are: |Option |Default |Description |`traceProcessors`| false | Trace inner custom processors (i.e., any `process` configured in the route). |`disableCoreProcessors`| false | Disable any inner core processors (any core DSL processor provided in the route, for example `bean`, `log`, ...). -|`excludePatterns` | | Sets exclude pattern that will disable tracing for those spans that matches the pattern. The variable is a comma separated values of filters to execute (eg, `log*,direct*,setBody*`, ...) +| `excludePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to exclude from tracing. Spans matching these patterns will be disabled. If nothing is specified, no processors are excluded by default. +| `includePatterns` | | A comma-separated list of patterns (e.g., `log*,direct*,setBody*`) to explicitly include in a trace. Spans matching these patterns will be enabled. If nothing is specified, all processors are included by default. |`traceHeadersInclusion`| false | Add the generated telemetry `CAMEL_TRACE_ID` and `CAMEL_SPAN_ID` Exchange headers. |======================================================================= diff --git a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/TraceProcessorsInterceptStrategy.java b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/TraceProcessorsInterceptStrategy.java index bad5cadafaa8..5369cba95192 100644 --- a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/TraceProcessorsInterceptStrategy.java +++ b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/TraceProcessorsInterceptStrategy.java @@ -59,7 +59,7 @@ public class TraceProcessorsInterceptStrategy implements InterceptStrategy { String processorName = processorDefinition.getId() + "-" + processorDefinition.getShortName(); if ((isCoreProcessEnabled(tracer.isDisableCoreProcessors(), processorDefinition.getShortName()) || isCustomProcessEnabled(tracer.isTraceProcessors(), processorDefinition.getShortName())) - && !tracer.exclude(processorName, exchange.getContext())) { + && tracer.match(processorName, exchange.getContext())) { tracer.beginProcessorSpan(exchange, processorName); try { processor.process(exchange); @@ -78,7 +78,7 @@ public class TraceProcessorsInterceptStrategy implements InterceptStrategy { boolean isTraceProcessor = (isCoreProcessEnabled(tracer.isDisableCoreProcessors(), processorDefinition.getShortName()) || isCustomProcessEnabled(tracer.isTraceProcessors(), processorDefinition.getShortName())) - && !tracer.exclude(processorName, exchange.getContext()); + && tracer.match(processorName, exchange.getContext()); if (isTraceProcessor) { try { tracer.beginProcessorSpan(exchange, processorName); diff --git a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/Tracer.java b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/Tracer.java index 9677ee55e505..940b9878befc 100644 --- a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/Tracer.java +++ b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/Tracer.java @@ -55,6 +55,7 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi * Component configuration */ private String excludePatterns; + private String includePatterns; private boolean traceProcessors; private boolean disableCoreProcessors; private boolean traceHeadersInclusion; @@ -89,6 +90,15 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi this.excludePatterns = excludePatterns; } + @ManagedAttribute + public String getIncludePatterns() { + return includePatterns; + } + + public void setIncludePatterns(String includePatterns) { + this.includePatterns = includePatterns; + } + @ManagedAttribute public boolean isTraceHeadersInclusion() { return traceHeadersInclusion; @@ -185,6 +195,13 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi camelContext.getRoutePolicyFactories().remove(this); } + public boolean match(String endpointUri, CamelContext context) { + boolean included = includePatterns == null || include(endpointUri, context); + boolean excluded = exclude(endpointUri, context); + + return included && !excluded; + } + public boolean exclude(String endpointUri, CamelContext context) { if (endpointUri != null && excludePatterns != null) { for (String pattern : excludePatterns.split(",")) { @@ -197,6 +214,20 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi return false; } + public boolean include(String endpointUri, CamelContext context) { + if (endpointUri != null && includePatterns != null) { + for (String pattern : includePatterns.split(",")) { + pattern = pattern.trim(); + + if (EndpointHelper.matchEndpoint(context, endpointUri, pattern)) { + return true; + } + } + } + + return false; + } + private final class TracingEventNotifier extends EventNotifierSupport { public TracingEventNotifier() { @@ -210,16 +241,16 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi public void notify(CamelEvent event) throws Exception { try { if (event instanceof CamelEvent.ExchangeSendingEvent ese) { - if (exclude(ese.getEndpoint().getEndpointUri(), ese.getExchange().getContext())) { - LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", ese.getEndpoint()); - } else { + if (match(ese.getEndpoint().getEndpointUri(), ese.getExchange().getContext())) { beginEventSpan(ese.getExchange(), ese.getEndpoint(), Op.EVENT_SENT); + } else { + LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", ese.getEndpoint()); } } else if (event instanceof CamelEvent.ExchangeSentEvent ese) { - if (exclude(ese.getEndpoint().getEndpointUri(), ese.getExchange().getContext())) { - LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", ese.getEndpoint()); - } else { + if (match(ese.getEndpoint().getEndpointUri(), ese.getExchange().getContext())) { endEventSpan(ese.getExchange(), ese.getEndpoint()); + } else { + LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", ese.getEndpoint()); } } } catch (Exception t) { @@ -233,10 +264,10 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi @Override public void onExchangeBegin(Route route, Exchange exchange) { try { - if (exclude(route.getEndpoint().getEndpointUri(), exchange.getContext())) { - LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", route.getEndpoint()); - } else { + if (match(route.getEndpoint().getEndpointUri(), exchange.getContext())) { beginEventSpan(exchange, route.getEndpoint(), Op.EVENT_RECEIVED); + } else { + LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", route.getEndpoint()); } } catch (Exception t) { LOG.warn("Tracing: Failed to capture tracing data. This exception is ignored.", t); @@ -246,10 +277,10 @@ public abstract class Tracer extends ServiceSupport implements CamelTracingServi @Override public void onExchangeDone(Route route, Exchange exchange) { try { - if (exclude(route.getEndpoint().getEndpointUri(), exchange.getContext())) { - LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", route.getEndpoint()); - } else { + if (match(route.getEndpoint().getEndpointUri(), exchange.getContext())) { endEventSpan(exchange, route.getEndpoint()); + } else { + LOG.debug("Tracing: endpoint {} is explicitly excluded, skipping.", route.getEndpoint()); } } catch (Exception t) { LOG.warn("Tracing: Failed to capture tracing data. This exception is ignored.", t); diff --git a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerExcludePatternsTest.java b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerExcludePatternsTest.java new file mode 100644 index 000000000000..ef589bc09d02 --- /dev/null +++ b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerExcludePatternsTest.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.telemetry; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.telemetry.mock.MockTracer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class TracerExcludePatternsTest { + + @Test + void shouldReturnTrueWhenEndpointMatchesPattern() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer();) { + tracer.setExcludePatterns("direct:foo,direct:bar"); + + boolean result = tracer.exclude("direct:foo", ctx); + + assertTrue(result); + } catch (Exception e) { + fail(); + } + } + + @Test + void shouldReturnFalseWhenEndpointDoesNotMatchPattern() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:foo,direct:bar"); + + boolean result = tracer.exclude("direct:baz", ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldTrimPatternsBeforeMatching() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns(" direct:foo , direct:bar "); + + boolean result = tracer.exclude("direct:bar", ctx); + + assertTrue(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnFalseWhenEndpointUriIsNull() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:foo"); + + boolean result = tracer.exclude(null, ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldSupportWildcardPatterns() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:*"); + + boolean result = tracer.exclude("direct:test", ctx); + + assertTrue(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldNotMatchWildcardPatternWithDifferentPrefix() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:*"); + + boolean result = tracer.exclude("seda:orders", ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldMatchMultipleWildcardPatterns() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:*,seda:*"); + + assertTrue(tracer.exclude("direct:test", ctx)); + assertTrue(tracer.exclude("seda:test", ctx)); + assertFalse(tracer.exclude("vm:test", ctx)); + } catch (Exception e) { + fail(e); + } + } +} diff --git a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerIncludePatternsTest.java b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerIncludePatternsTest.java new file mode 100644 index 000000000000..de81ea61ca9a --- /dev/null +++ b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerIncludePatternsTest.java @@ -0,0 +1,135 @@ +/* + * 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.telemetry; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.telemetry.mock.MockTracer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class TracerIncludePatternsTest { + + @Test + void shouldReturnTrueWhenEndpointMatchesIncludePattern() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:foo,direct:bar"); + + boolean result = tracer.include("direct:foo", ctx); + + assertTrue(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnFalseWhenEndpointDoesNotMatchIncludePattern() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:foo,direct:bar"); + + boolean result = tracer.include("direct:baz", ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldTrimIncludePatternsBeforeMatching() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns(" direct:foo , direct:bar "); + + boolean result = tracer.include("direct:bar", ctx); + + assertTrue(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnFalseWhenEndpointUriIsNull() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:foo"); + + boolean result = tracer.include(null, ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldMatchWildcardIncludePattern() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*"); + + boolean result = tracer.include("direct:test", ctx); + + assertTrue(result); + + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldNotMatchWildcardIncludePatternWithDifferentPrefix() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*"); + + boolean result = tracer.include("seda:test", ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldMatchMultipleWildcardIncludePatterns() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*,seda:*"); + + assertTrue(tracer.include("direct:test", ctx)); + assertTrue(tracer.include("seda:test", ctx)); + assertFalse(tracer.include("vm:test", ctx)); + } catch (Exception e) { + fail(e); + } + } +} diff --git a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerMatchTest.java b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerMatchTest.java new file mode 100644 index 000000000000..45c23a9493a8 --- /dev/null +++ b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/TracerMatchTest.java @@ -0,0 +1,107 @@ +/* + * 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.telemetry; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.telemetry.mock.MockTracer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class TracerMatchTest { + + @Test + void shouldReturnTrueWhenIncludedAndNotExcluded() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*"); + tracer.setExcludePatterns("direct:admin"); + + assertTrue(tracer.match("direct:orders", ctx)); + assertFalse(tracer.match("direct:admin", ctx)); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnFalseWhenEndpointIsNotIncluded() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*"); + + boolean result = tracer.match("seda:test", ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnTrueWhenNoIncludePatternsAndNotExcluded() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setExcludePatterns("direct:admin"); + + assertTrue(tracer.match("seda:test", ctx)); + assertFalse(tracer.match("direct:admin", ctx)); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldReturnFalseWhenEndpointUriIsNull() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*"); + tracer.setExcludePatterns("direct:admin"); + + boolean result = tracer.match(null, ctx); + + assertFalse(result); + } catch (Exception e) { + fail(e); + } + } + + @Test + void shouldSupportMultipleIncludeAndExcludePatterns() { + try (CamelContext ctx = new DefaultCamelContext(); + Tracer tracer = new MockTracer()) { + + tracer.setIncludePatterns("direct:*,seda:*"); + tracer.setExcludePatterns("direct:admin,seda:internal"); + + assertTrue(tracer.match("direct:test", ctx)); + assertTrue(tracer.match("seda:orders", ctx)); + + assertFalse(tracer.match("direct:admin", ctx)); + assertFalse(tracer.match("seda:internal", ctx)); + } catch (Exception e) { + fail(e); + } + } +}
