From 7d66954a446345fd3863946f02e8ef6361733003 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:49:32 +0100 Subject: [PATCH 1/9] fix comment --- .../fileconfig/ComposableRuleBasedSamplerFactory.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java index aea589ede38..b89a7e4304a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java @@ -53,12 +53,14 @@ public ComposableSampler create( rule -> { AttributeMatcher valueMatcher = attributeValuesMatcher(rule.getAttributeValues()); AttributeMatcher patternMatcher = attributePatternsMatcher(rule.getAttributePatterns()); - // TODO: should be null when omitted but is empty + // empty list is provided when field is omitted, but should be treated as null + // as empty include list will exclude all Set matchingParents = rule.getParent() != null && !rule.getParent().isEmpty() ? new HashSet<>(rule.getParent()) : null; - // TODO: should be null when omitted but is empty + // empty list is provided when field is omitted, but should be treated as null + // as empty include list will exclude all Set matchingSpanKinds = rule.getSpanKinds() != null && !rule.getSpanKinds().isEmpty() ? rule.getSpanKinds().stream() From c0e641d60b270979447f3129cfbabaad9f324b14 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:49:45 +0100 Subject: [PATCH 2/9] fix for composable rule based sampler --- .../fileconfig/ComposableRuleBasedSamplerFactory.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java index b89a7e4304a..04df4c4db21 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java @@ -100,10 +100,16 @@ private static AttributeMatcher attributePatternsMatcher( if (attributePatternsModel == null) { return null; } + List included = attributePatternsModel.getIncluded(); + // empty list is provided when field is omitted, but should be treated as null as empty include + // list will exclude all + if (included != null && included.isEmpty()) { + included = null; + } return new AttributeMatcher( requireNonNull(attributePatternsModel.getKey(), "attribute_patterns key"), IncludeExcludePredicate.createPatternMatching( - attributePatternsModel.getIncluded(), attributePatternsModel.getExcluded())); + included, attributePatternsModel.getExcluded())); } // Visible for testing From 13162bf50ddec49c8af509db7222109ec9276ed1 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:50:01 +0100 Subject: [PATCH 3/9] fix metric views --- .../sdk/extension/incubator/fileconfig/ViewFactory.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java index 2f4c598201b..dabfe2a3e3a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java @@ -34,6 +34,11 @@ public View create(ViewStreamModel model, DeclarativeConfigContext context) { IncludeExcludeModel attributeKeys = model.getAttributeKeys(); if (attributeKeys != null) { List included = attributeKeys.getIncluded(); + // an empty list is provided when field is omitted in yaml, so we need to treat it as null to + // avoid creating a filter that will include nothing + if (included != null && included.isEmpty()) { + included = null; + } List excluded = attributeKeys.getExcluded(); if (included != null || excluded != null) { builder.setAttributeFilter(IncludeExcludePredicate.createExactMatching(included, excluded)); From d159a573daefb791a3ae765af14033d16d02f0bd Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:50:12 +0100 Subject: [PATCH 4/9] fix typo in method name --- .../fileconfig/ComposableRuleBasedSamplerFactoryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java index 8a8da213fd1..68525e0abd0 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactoryTest.java @@ -162,7 +162,7 @@ private static Stream createTestCases() { private static final AttributeKey HTTP_PATH = AttributeKey.stringKey("http.path"); @ParameterizedTest - @MethodSource("declarativeCOnfigSamplingPredicateArgs") + @MethodSource("declarativeConfigSamplingPredicateArgs") void declarativeConfigSamplingPredicate( DeclarativeConfigSamplingPredicate predicate, Context context, @@ -174,7 +174,7 @@ void declarativeConfigSamplingPredicate( } @SuppressWarnings("unused") - private static Stream declarativeCOnfigSamplingPredicateArgs() { + private static Stream declarativeConfigSamplingPredicateArgs() { DeclarativeConfigSamplingPredicate matchAll = new DeclarativeConfigSamplingPredicate(null, null, null, null); DeclarativeConfigSamplingPredicate valuesMatcher = From 4c81dc105c5c8a505b27ed2553e35542ab9135f0 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:50:19 +0100 Subject: [PATCH 5/9] improve javadoc --- .../sdk/common/internal/IncludeExcludePredicate.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java index dd6ba4e63b4..45f0387fcce 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java @@ -57,6 +57,9 @@ private IncludeExcludePredicate( /** * Create a (case-sensitive) exact matching include exclude predicate. * + *

When {@code included} is an empty collection, the predicate will exclude all values, use + * {@literal null} to include all values by default.> + * * @throws IllegalArgumentException if {@code included} AND {@code excluded} are null. */ public static Predicate createExactMatching( @@ -67,6 +70,9 @@ public static Predicate createExactMatching( /** * Create a pattern matching include exclude predicate. * + *

When {@code included} is an empty collection, the predicate will exclude all values, use + * {@literal null} to include all values by default.> + * *

See {@link GlobUtil} for pattern matching details. * * @throws IllegalArgumentException if {@code included} AND {@code excluded} are null. From 5035876ac301ff56ad2af352bbea41422ee48517 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 16 Mar 2026 09:26:28 +0100 Subject: [PATCH 6/9] simpler generic approach --- .../ComposableRuleBasedSamplerFactory.java | 8 +----- .../incubator/fileconfig/ResourceFactory.java | 5 ---- .../internal/IncludeExcludePredicate.java | 25 +++++++++++------ .../internal/IncludeExcludePredicateTest.java | 28 +++++++++++++------ .../sdk/metrics/ViewBuilder.java | 3 ++ 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java index 04df4c4db21..b89a7e4304a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java @@ -100,16 +100,10 @@ private static AttributeMatcher attributePatternsMatcher( if (attributePatternsModel == null) { return null; } - List included = attributePatternsModel.getIncluded(); - // empty list is provided when field is omitted, but should be treated as null as empty include - // list will exclude all - if (included != null && included.isEmpty()) { - included = null; - } return new AttributeMatcher( requireNonNull(attributePatternsModel.getKey(), "attribute_patterns key"), IncludeExcludePredicate.createPatternMatching( - included, attributePatternsModel.getExcluded())); + attributePatternsModel.getIncluded(), attributePatternsModel.getExcluded())); } // Visible for testing diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java index 3f849c836af..e43de54a34c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ResourceFactory.java @@ -93,11 +93,6 @@ private static Predicate detectorAttributeFilter( if (included == null && excluded == null) { return ResourceFactory::matchAll; } - // when "included" is omitted in configuration, we get an empty list - // in this context it should be interpreted as "include everything" - if (included != null && included.isEmpty()) { - included = null; - } return IncludeExcludePredicate.createPatternMatching(included, excluded); } } diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java index 45f0387fcce..66518d76310 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java @@ -38,8 +38,8 @@ private IncludeExcludePredicate( @Nullable Collection excluded, boolean globMatchingEnabled) { this.globMatchingEnabled = globMatchingEnabled; - this.included = included == null ? null : new LinkedHashSet<>(included); - this.excluded = excluded == null ? null : new LinkedHashSet<>(excluded); + this.included = copyIfNotEmpty(included); + this.excluded = copyIfNotEmpty(excluded); if (this.included != null && this.excluded != null) { this.predicate = includedPredicate(this.included, globMatchingEnabled) @@ -57,10 +57,12 @@ private IncludeExcludePredicate( /** * Create a (case-sensitive) exact matching include exclude predicate. * - *

When {@code included} is an empty collection, the predicate will exclude all values, use - * {@literal null} to include all values by default.> + *

When {@code included} is empty or {@literal null}, all values are included by default. * - * @throws IllegalArgumentException if {@code included} AND {@code excluded} are null. + *

When {@code excluded} is empty or {@literal null}, no value is excluded by default. + * + * @throws IllegalArgumentException if both {@code included} AND {@code excluded} are null or + * empty. */ public static Predicate createExactMatching( @Nullable Collection included, @Nullable Collection excluded) { @@ -70,12 +72,14 @@ public static Predicate createExactMatching( /** * Create a pattern matching include exclude predicate. * - *

When {@code included} is an empty collection, the predicate will exclude all values, use - * {@literal null} to include all values by default.> + *

When {@code included} is empty or {@literal null}, all values are included by default. + * + *

When {@code excluded} is empty or {@literal null}, no value is excluded by default. * *

See {@link GlobUtil} for pattern matching details. * - * @throws IllegalArgumentException if {@code included} AND {@code excluded} are null. + * @throws IllegalArgumentException if both {@code included} AND {@code excluded} are null or + * empty. */ public static Predicate createPatternMatching( @Nullable Collection included, @Nullable Collection excluded) { @@ -125,4 +129,9 @@ private static Predicate excludedPredicate( } return result; } + + @Nullable + private static Set copyIfNotEmpty(@Nullable Collection collection) { + return collection == null || collection.isEmpty() ? null : new LinkedHashSet<>(collection); + } } diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java index 55b2c02472f..a74066c6871 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java @@ -8,10 +8,14 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.Collection; import java.util.Collections; import java.util.function.Predicate; import java.util.stream.Stream; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -26,8 +30,6 @@ class IncludeExcludePredicateTest { IncludeExcludePredicate.createExactMatching(singletonList("foo"), singletonList("bar")); private static final Predicate EXACT_MULTI = IncludeExcludePredicate.createExactMatching(asList("foo", "fooo"), asList("bar", "barr")); - public static final Predicate EXACT_INCLUDE_NONE = - IncludeExcludePredicate.createExactMatching(Collections.emptyList(), null); private static final Predicate PATTERN_INCLUDE = IncludeExcludePredicate.createPatternMatching(singletonList("f?o"), null); @@ -37,8 +39,6 @@ class IncludeExcludePredicateTest { IncludeExcludePredicate.createPatternMatching(singletonList("f?o"), singletonList("b?r")); private static final Predicate PATTERN_MULTI = IncludeExcludePredicate.createPatternMatching(asList("f?o", "f?oo"), asList("b?r", "b?rr")); - public static final Predicate PATTERN_INCLUDE_NONE = - IncludeExcludePredicate.createPatternMatching(Collections.emptyList(), null); @ParameterizedTest @MethodSource("testArgs") @@ -75,8 +75,6 @@ private static Stream testArgs() { Arguments.of(EXACT_MULTI, "bar", false), Arguments.of(EXACT_MULTI, "barr", false), Arguments.of(EXACT_MULTI, "baz", false), - // include none - Arguments.of(EXACT_INCLUDE_NONE, "foo", false), // pattern matching // include only Arguments.of(PATTERN_INCLUDE, "foo", true), @@ -106,9 +104,7 @@ private static Stream testArgs() { Arguments.of(PATTERN_MULTI, "bAr", false), Arguments.of(PATTERN_MULTI, "barr", false), Arguments.of(PATTERN_MULTI, "bArr", false), - Arguments.of(PATTERN_MULTI, "baz", false), - // include none - Arguments.of(PATTERN_INCLUDE_NONE, "foo", false)); + Arguments.of(PATTERN_MULTI, "baz", false)); } @ParameterizedTest @@ -140,4 +136,18 @@ private static Stream stringRepresentationArgs() { PATTERN_MULTI, "IncludeExcludePredicate{globMatchingEnabled=true, included=[f?o, f?oo], excluded=[b?r, b?rr]}")); } + + @Test + void try_includeExcludeNone() { + expectIllegalArgument(null, null); + expectIllegalArgument(Collections.emptyList(), null); + expectIllegalArgument(null, Collections.emptyList()); + expectIllegalArgument(Collections.emptyList(), Collections.emptyList()); + } + + private static void expectIllegalArgument( + @Nullable Collection included, @Nullable Collection excluded) { + assertThatThrownBy(() -> IncludeExcludePredicate.createExactMatching(included, excluded)) + .isInstanceOf(IllegalArgumentException.class); + } } diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index d2ba1b53e33..082e5bc6c18 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -74,6 +74,9 @@ public ViewBuilder setAggregation(Aggregation aggregation) { */ public ViewBuilder setAttributeFilter(Set keysToRetain) { Objects.requireNonNull(keysToRetain, "keysToRetain"); + if (keysToRetain.isEmpty()) { + return setAttributeFilter(s -> false); + } return setAttributeFilter(IncludeExcludePredicate.createExactMatching(keysToRetain, null)); } From 65ef3601dc16f8684f94f409396d480e70e1007d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 16 Mar 2026 09:42:17 +0100 Subject: [PATCH 7/9] simplify where we can --- .../sdk/extension/incubator/fileconfig/ViewFactory.java | 9 +-------- .../java/io/opentelemetry/sdk/metrics/ViewBuilder.java | 2 ++ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java index dabfe2a3e3a..1860c3dea9c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ViewFactory.java @@ -34,15 +34,8 @@ public View create(ViewStreamModel model, DeclarativeConfigContext context) { IncludeExcludeModel attributeKeys = model.getAttributeKeys(); if (attributeKeys != null) { List included = attributeKeys.getIncluded(); - // an empty list is provided when field is omitted in yaml, so we need to treat it as null to - // avoid creating a filter that will include nothing - if (included != null && included.isEmpty()) { - included = null; - } List excluded = attributeKeys.getExcluded(); - if (included != null || excluded != null) { - builder.setAttributeFilter(IncludeExcludePredicate.createExactMatching(included, excluded)); - } + builder.setAttributeFilter(IncludeExcludePredicate.createExactMatching(included, excluded)); } if (model.getAggregation() != null) { builder.setAggregation( diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java index 082e5bc6c18..a78b5fbe41e 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/ViewBuilder.java @@ -75,6 +75,8 @@ public ViewBuilder setAggregation(Aggregation aggregation) { public ViewBuilder setAttributeFilter(Set keysToRetain) { Objects.requireNonNull(keysToRetain, "keysToRetain"); if (keysToRetain.isEmpty()) { + // include/exclude predicate requires to include or exclude at least one, we have to skip it + // when we don't want to include any key. return setAttributeFilter(s -> false); } return setAttributeFilter(IncludeExcludePredicate.createExactMatching(keysToRetain, null)); From 0f2f858fe365466f5701f453397454d5c1b1a9aa Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 16 Mar 2026 09:47:35 +0100 Subject: [PATCH 8/9] revert comment change --- .../fileconfig/ComposableRuleBasedSamplerFactory.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java index b89a7e4304a..aea589ede38 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ComposableRuleBasedSamplerFactory.java @@ -53,14 +53,12 @@ public ComposableSampler create( rule -> { AttributeMatcher valueMatcher = attributeValuesMatcher(rule.getAttributeValues()); AttributeMatcher patternMatcher = attributePatternsMatcher(rule.getAttributePatterns()); - // empty list is provided when field is omitted, but should be treated as null - // as empty include list will exclude all + // TODO: should be null when omitted but is empty Set matchingParents = rule.getParent() != null && !rule.getParent().isEmpty() ? new HashSet<>(rule.getParent()) : null; - // empty list is provided when field is omitted, but should be treated as null - // as empty include list will exclude all + // TODO: should be null when omitted but is empty Set matchingSpanKinds = rule.getSpanKinds() != null && !rule.getSpanKinds().isEmpty() ? rule.getSpanKinds().stream() From f7e47c44e3044994eae770855ff3b0cb5583f253 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 18 Mar 2026 08:49:06 +0100 Subject: [PATCH 9/9] include all by default when both are empty or null --- .../internal/IncludeExcludePredicate.java | 14 +++------ .../internal/IncludeExcludePredicateTest.java | 30 +++++++++++++------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java index 66518d76310..5475c1e2f4d 100644 --- a/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java +++ b/sdk/common/src/main/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicate.java @@ -44,13 +44,13 @@ private IncludeExcludePredicate( this.predicate = includedPredicate(this.included, globMatchingEnabled) .and(excludedPredicate(this.excluded, globMatchingEnabled)); - } else if (this.included == null && this.excluded != null) { + } else if (this.excluded != null) { this.predicate = excludedPredicate(this.excluded, globMatchingEnabled); - } else if (this.excluded == null && this.included != null) { + } else if (this.included != null) { this.predicate = includedPredicate(this.included, globMatchingEnabled); } else { - throw new IllegalArgumentException( - "At least one of includedPatterns or excludedPatterns must not be null"); + // include everything by default if both included and excluded are null or empt + this.predicate = s -> true; } } @@ -60,9 +60,6 @@ private IncludeExcludePredicate( *

When {@code included} is empty or {@literal null}, all values are included by default. * *

When {@code excluded} is empty or {@literal null}, no value is excluded by default. - * - * @throws IllegalArgumentException if both {@code included} AND {@code excluded} are null or - * empty. */ public static Predicate createExactMatching( @Nullable Collection included, @Nullable Collection excluded) { @@ -77,9 +74,6 @@ public static Predicate createExactMatching( *

When {@code excluded} is empty or {@literal null}, no value is excluded by default. * *

See {@link GlobUtil} for pattern matching details. - * - * @throws IllegalArgumentException if both {@code included} AND {@code excluded} are null or - * empty. */ public static Predicate createPatternMatching( @Nullable Collection included, @Nullable Collection excluded) { diff --git a/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java b/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java index a74066c6871..5eb6e0a02f7 100644 --- a/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java +++ b/sdk/common/src/test/java/io/opentelemetry/sdk/common/internal/IncludeExcludePredicateTest.java @@ -8,8 +8,8 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.function.Predicate; @@ -138,16 +138,28 @@ private static Stream stringRepresentationArgs() { } @Test - void try_includeExcludeNone() { - expectIllegalArgument(null, null); - expectIllegalArgument(Collections.emptyList(), null); - expectIllegalArgument(null, Collections.emptyList()); - expectIllegalArgument(Collections.emptyList(), Collections.emptyList()); + void emptyOrNullShouldIncludeAll() { + shouldIncludeAll(null, null); + shouldIncludeAll(Collections.emptyList(), null); + shouldIncludeAll(null, Collections.emptyList()); + shouldIncludeAll(Collections.emptyList(), Collections.emptyList()); } - private static void expectIllegalArgument( + private static void shouldIncludeAll( @Nullable Collection included, @Nullable Collection excluded) { - assertThatThrownBy(() -> IncludeExcludePredicate.createExactMatching(included, excluded)) - .isInstanceOf(IllegalArgumentException.class); + Arrays.asList("foo", "fooo", "fOo", "FOO", "bar", "bAr", "barr", "bArr", "baz") + .forEach( + s -> { + Predicate exactMatching = + IncludeExcludePredicate.createExactMatching(included, excluded); + assertThat(exactMatching.test(s)).isTrue(); + assertThat(exactMatching.toString()) + .isEqualTo("IncludeExcludePredicate{globMatchingEnabled=false}"); + Predicate patternMatching = + IncludeExcludePredicate.createPatternMatching(included, excluded); + assertThat(patternMatching.test(s)).isTrue(); + assertThat(patternMatching.toString()) + .isEqualTo("IncludeExcludePredicate{globMatchingEnabled=true}"); + }); } }