From 306ba5c3f3c9d5b578acfa34d076458c4d506042 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 1 Jun 2022 13:54:45 +0100 Subject: [PATCH] Refactoring in ContextContainer and implementation (#10) * Refactoring in ContextContainer Rename SimpleContextContainer to DefaultContextContainer. Drop ContextAccessorLoader and ThreadLocalAccessorLoader in favor of configuring instances of those directly on DefaultContextContainer. The layers above (e.g. Web Framework, GraphQL transport, etc.) have the responsibility to know what accessors should be used, and therefore ContextContainer should be directly configurable. In other words it cannot be a global mechanism like ServiceLoader. * Drop NOOP constants and implementations If a ContextContainerPropagator isn't found, it should be an IllegalStateException. It means we don't know how to save to a specific external context, and something is wrong. Or otherwise it would silently not propagate. If a ContextContainer isn't present, there are several cases. - the code expects a ContextContainer and therefore needs to check through the isNoop() method anyway to protect itself, but it might forget to do so. - the code expects there may or may not be a ContextContainer, but wants to start a new one if not found. Here it also needs to check isNoop(), but if it doesn't do so, it could even lead to errors in code that expects an actual ContextContainer and not a noop. - only code that expects there may or may not be a ContextContainer and doesn't care either way benefits; arguably though a noop lurking always has the potential of causing side effects and surprises. For ContextContainerPropagator, we now always throw IllegalStateException if there isn't a compatible one registered. For ContextContainer, restoreFrom raises ISE while separately there is a restoreIfPresentFrom that returns null if not found. * Polishing and minor refactoring Ordering of methods in DefaultContextContainer consistent with the order in ContextContainer. Rename ContextContainerPropagator to ContextContainerAdapter. --- README.md | 2 +- .../ContextAccessorLoader.java | 57 --------- .../contextpropagation/ContextContainer.java | 118 ++++-------------- ...ator.java => ContextContainerAdapter.java} | 54 +++----- .../ContextContainerAdapterLoader.java | 55 ++++++++ .../ContextContainerPropagatorLoader.java | 53 -------- ...iner.java => DefaultContextContainer.java} | 87 ++++++++----- .../ThreadLocalAccessorLoader.java | 34 ----- .../InstrumentationTests.java | 3 +- .../SimpleThreadLocalAccessorTests.java | 5 +- ...ter.contextpropagation.ThreadLocalAccessor | 1 - 11 files changed, 157 insertions(+), 312 deletions(-) delete mode 100644 context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextAccessorLoader.java rename context-propagation-api/src/main/java/io/micrometer/contextpropagation/{ContextContainerPropagator.java => ContextContainerAdapter.java} (66%) create mode 100644 context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapterLoader.java delete mode 100644 context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagatorLoader.java rename context-propagation-api/src/main/java/io/micrometer/contextpropagation/{SimpleContextContainer.java => DefaultContextContainer.java} (63%) delete mode 100644 context-propagation-api/src/main/java/io/micrometer/contextpropagation/ThreadLocalAccessorLoader.java delete mode 100644 context-propagation-api/src/test/resources/META-INF/services/io.micrometer.contextpropagation.ThreadLocalAccessor diff --git a/README.md b/README.md index e8aa129..ad22b97 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Glossary * `Context` - mean of communication. That can be e.g. Reactor `Context`, Reactor Netty `Channel` etc. * `ContextAccessor` - what to take from the Context and put it to the container and vice versa (e.g. if there's a Reactor Context I want to take out and put back a value for key `foo`) * `ThreadLocalAccessor` - how to take from thread local and put it to the context container and vice versa. (e.g. `ObservationThreadLocalAccessor` will take the value of the current `Observation`) -* `ContextContainerPropagator` - how to write the `ContextContainer` to a Context and from it (e.g. `ReactorContextContainerPropagator` - how to read and write the container to Reactor Context) +* `ContextContainerAdapter` - how to write the `ContextContainer` to a Context and from it (e.g. `ReactorContextContainerAdapter` - how to read and write the container to Reactor Context) * `Namespace` logical grouping for `ThreadLocalAccessor`s. Can be used for filtering out thread local accessors. ## Contributing diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextAccessorLoader.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextAccessorLoader.java deleted file mode 100644 index 40c611b..0000000 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextAccessorLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed 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 - * - * https://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 io.micrometer.contextpropagation; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Loads {@link ThreadLocalAccessor} and {@link ContextAccessor}. - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -final class ContextAccessorLoader { - - private static final ServiceLoader propagators = ServiceLoader.load(ContextAccessor.class); - - private static final Map> cache = new ConcurrentHashMap<>(); - - static List getAccessorsToCapture(Object ctx) { - return cache.computeIfAbsent(ctx.getClass(), aClass -> { - List accessors = new ArrayList<>(); - for (ContextAccessor accessor : propagators) { - if (accessor.canCaptureFrom(aClass)) { - accessors.add(accessor); - } - } - return accessors; - }); - } - - static List getAccessorsToRestore(Object ctx) { - return cache.computeIfAbsent(ctx.getClass(), aClass -> { - List accessors = new ArrayList<>(); - for (ContextAccessor accessor : propagators) { - if (accessor.canRestoreTo(aClass)) { - accessors.add(accessor); - } - } - return accessors; - }); - } -} diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainer.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainer.java index 311a6de..51e0523 100644 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainer.java +++ b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainer.java @@ -31,78 +31,6 @@ */ public interface ContextContainer { - /** - * A No-Op instance that does nothing. To be used instead of {@code null}. - */ - ContextContainer NOOP = new ContextContainer() { - @Override - public void captureValues(Object context) { - - } - - @Override - public T restoreValues(T context) { - return context; - } - - @Override - public T get(String key) { - return null; - } - - @Override - public boolean containsKey(String key) { - return false; - } - - @Override - public T put(String key, T value) { - return value; - } - - @Override - public T remove(String key) { - return null; - } - - @Override - public ContextContainer captureThreadLocalValues() { - return this; - } - - @Override - public ContextContainer captureThreadLocalValues(Predicate predicate) { - return this; - } - - @Override - public Scope restoreThreadLocalValues() { - return () -> { - }; - } - - @Override - public T saveTo(T context) { - return context; - } - - @Override - public boolean isNoOp() { - return true; - } - - @Override - public void tryScoped(Runnable action) { - action.run(); - } - - @Override - public T tryScoped(Supplier action) { - return action.get(); - } - }; - - /** * Gets an element from the container. * @@ -182,41 +110,53 @@ public T tryScoped(Supplier action) { * @param context context in which we want to store this container * @param type of the context * @return the context with the stored container + * @throws IllegalStateException if a {@link ContextContainerAdapter} + * that supports the given external context is not available */ T saveTo(T context); /** - * Restores the {@link ContextContainer} from the provided context. + * Restores the {@link ContextContainer} from the provided external context. * * @param context context from which we want to retrieve from {@link ContextContainer} * @param type of the context * @return the container retrieved from the given context + * @throws IllegalStateException if a {@link ContextContainerAdapter} + * that supports the given external context is not available, or if the + * external context does not have a {@link ContextContainer} saved + * @see #restoreIfPresentFrom(Object) */ @SuppressWarnings({"unchecked", "rawtypes"}) static ContextContainer restoreFrom(T context) { - ContextContainerPropagator propagator = ContextContainerPropagatorLoader.getPropagatorToRestore(context); - return propagator.restore(context); + ContextContainerAdapter adapter = ContextContainerAdapterLoader.getAdapterToRead(context); + return adapter.restore(context); } /** - * Removes the {@link ContextContainer} from the given context. + * Restores the {@link ContextContainer} from the provided external context. * - * @param context context from which we want to remove the {@link ContextContainer} + * @param context context from which we want to retrieve from {@link ContextContainer} * @param type of the context - * @return context with {@link ContextContainer} removed + * @return the container retrieved from the external context or {@code null} */ @SuppressWarnings({"unchecked", "rawtypes"}) - static T removeFrom(T context) { - ContextContainerPropagator propagator = ContextContainerPropagatorLoader.getPropagatorToRestore(context); - return (T) propagator.remove(context); + static ContextContainer restoreIfPresentFrom(T context) { + ContextContainerAdapter adapter = ContextContainerAdapterLoader.getAdapterToRead(context); + return adapter.restoreIfPresent(context); } /** - * Is this a noop implementation? + * Removes the {@link ContextContainer} from the given context. * - * @return {@code true} if this instance is a no-op + * @param context context from which we want to remove the {@link ContextContainer} + * @param type of the context + * @return context with {@link ContextContainer} removed */ - boolean isNoOp(); + @SuppressWarnings({"unchecked", "rawtypes"}) + static T removeFrom(T context) { + ContextContainerAdapter adapter = ContextContainerAdapterLoader.getAdapterToWrite(context); + return (T) adapter.remove(context); + } /** * Takes the runnable and runs it with thread local values available. @@ -237,16 +177,6 @@ static T removeFrom(T context) { T tryScoped(Supplier action); - /** - * Builds a new {@link ContextContainer}. - * - * @return a new {@link ContextContainer} - */ - static ContextContainer create() { - return new SimpleContextContainer(); - } - - /** * Propagates the context over the {@link Runnable}. * diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagator.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapter.java similarity index 66% rename from context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagator.java rename to context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapter.java index 0f5af9a..bb907d0 100644 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagator.java +++ b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapter.java @@ -19,7 +19,7 @@ /** * Abstraction to tell context propagation how to read from and write to - * a given context. To register your own {@link ContextContainerPropagator} + * a given context. To register your own {@link ContextContainerAdapter} * you have to register it using the {@link ServiceLoader} mechanism. * * @param context from which we read @@ -28,39 +28,7 @@ * @author Marcin Grzejszczak * @since 1.0.0 */ -public interface ContextContainerPropagator { - - /** - * No-Op instance of the {@link ContextContainerPropagator}. Does nothing. - */ - @SuppressWarnings("rawtypes") - ContextContainerPropagator NOOP = new ContextContainerPropagator() { - @Override - public Object save(ContextContainer contextContainer, Object context) { - return context; - } - - @Override - public ContextContainer restore(Object context) { - return ContextContainer.NOOP; - } - - @Override - public Object remove(Object ctx) { - return ctx; - } - - @Override - public boolean supportsSaveTo(Class contextType) { - return false; - } - - @Override - public boolean supportsRestoreFrom(Class contextType) { - return false; - } - - }; +public interface ContextContainerAdapter { /** * Save the {@link ContextContainer} to the external context. @@ -73,13 +41,23 @@ public boolean supportsRestoreFrom(Class contextType) { /** * Restore the {@link ContextContainer} from the external context. If the container - * is not there the implementation should return {@link ContextContainer#NOOP}. + * is not there, the implementation should raise {@link IllegalStateException}. * * @param context context from which we want to retrieve the {@link ContextContainer} - * @return container + * @return the container instance + * @throws IllegalStateException if no {@link ContextContainer} is found */ ContextContainer restore(READ context); + /** + * Restore the {@link ContextContainer} from the external context. If the container + * is not there, the implementation should raise {@link IllegalStateException}. + * + * @param context context from which we want to retrieve the {@link ContextContainer} + * @return the container instance or {@code null} + */ + ContextContainer restoreIfPresent(READ context); + /** * Removes the {@link ContextContainer} from the context. * @@ -91,14 +69,14 @@ public boolean supportsRestoreFrom(Class contextType) { /** * Checks if this implementation can work with the provided context for writing. * - * @return class type for which this propagator is applicable + * @return class type for which this adapter is applicable */ boolean supportsSaveTo(Class contextType); /** * Checks if this implementation can work with the provided context for reading. * - * @return class type for which this propagator is applicable + * @return class type for which this adapter is applicable */ boolean supportsRestoreFrom(Class contextType); } diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapterLoader.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapterLoader.java new file mode 100644 index 0000000..a7bfe6c --- /dev/null +++ b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerAdapterLoader.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.micrometer.contextpropagation; + +import java.util.Map; +import java.util.ServiceLoader; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Loads {@link ThreadLocalAccessor} and {@link ContextAccessor}. + */ +@SuppressWarnings({ "rawtypes", "unchecked" }) +final class ContextContainerAdapterLoader { + + private static final ServiceLoader adapters = ServiceLoader.load(ContextContainerAdapter.class); + + private static final Map cache = new ConcurrentHashMap<>(); + + static ContextContainerAdapter getAdapterToWrite(Object context) { + return cache.computeIfAbsent(context.getClass(), aClass -> { + for (ContextContainerAdapter contextContainerAdapter : adapters) { + if (contextContainerAdapter.supportsSaveTo(aClass)) { + return contextContainerAdapter; + } + } + throw new IllegalStateException( + "No ContextContainerAdapter for context type: " + context.getClass()); + }); + } + + static ContextContainerAdapter getAdapterToRead(Object context) { + return cache.computeIfAbsent(context.getClass(), aClass -> { + for (ContextContainerAdapter contextContainerAdapter : adapters) { + if (contextContainerAdapter.supportsRestoreFrom(aClass)) { + return contextContainerAdapter; + } + } + throw new IllegalStateException( + "No ContextContainerAdapter for context type: " + context.getClass()); + }); + } +} diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagatorLoader.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagatorLoader.java deleted file mode 100644 index 536206b..0000000 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ContextContainerPropagatorLoader.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed 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 - * - * https://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 io.micrometer.contextpropagation; - -import java.util.Map; -import java.util.ServiceLoader; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Loads {@link ThreadLocalAccessor} and {@link ContextAccessor}. - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -final class ContextContainerPropagatorLoader { - - private static final ServiceLoader propagators = ServiceLoader.load(ContextContainerPropagator.class); - - private static final Map cache = new ConcurrentHashMap<>(); - - static ContextContainerPropagator getPropagatorToSave(Object ctx) { - return cache.computeIfAbsent(ctx.getClass(), aClass -> { - for (ContextContainerPropagator contextContainerPropagator : propagators) { - if (contextContainerPropagator.supportsSaveTo(aClass)) { - return contextContainerPropagator; - } - } - return ContextContainerPropagator.NOOP; - }); - } - - static ContextContainerPropagator getPropagatorToRestore(Object ctx) { - return cache.computeIfAbsent(ctx.getClass(), aClass -> { - for (ContextContainerPropagator contextContainerPropagator : propagators) { - if (contextContainerPropagator.supportsRestoreFrom(aClass)) { - return contextContainerPropagator; - } - } - return ContextContainerPropagator.NOOP; - }); - } -} diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/SimpleContextContainer.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/DefaultContextContainer.java similarity index 63% rename from context-propagation-api/src/main/java/io/micrometer/contextpropagation/SimpleContextContainer.java rename to context-propagation-api/src/main/java/io/micrometer/contextpropagation/DefaultContextContainer.java index 8b8d0af..e9c97e3 100644 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/SimpleContextContainer.java +++ b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/DefaultContextContainer.java @@ -15,6 +15,8 @@ */ package io.micrometer.contextpropagation; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -31,41 +33,23 @@ * @since 1.0.0 */ @SuppressWarnings({ "rawtypes", "unchecked" }) -class SimpleContextContainer implements ContextContainer { +public class DefaultContextContainer implements ContextContainer { private final Map values = new ConcurrentHashMap<>(); + private final List> contextAccessors; + private final List threadLocalAccessors; + private final Map> contextAccessorCache = new ConcurrentHashMap<>(); + private final List> predicates = new CopyOnWriteArrayList<>(); - SimpleContextContainer() { - this.threadLocalAccessors = ThreadLocalAccessorLoader.getThreadLocalAccessors(); - } + public DefaultContextContainer( + List> contextAccessors, List threadLocalAccessors) { - @Override - public void captureValues(Object context) { - List contextAccessorsForSet = ContextAccessorLoader.getAccessorsToCapture(context); - for (ContextAccessor contextAccessor : contextAccessorsForSet) { - contextAccessor.captureValues(context, this); - } - } - - @Override - public T restoreValues(T context) { - T mergedContext = context; - List contextAccessorsForGet = ContextAccessorLoader.getAccessorsToRestore(context); - for (ContextAccessor contextAccessor : contextAccessorsForGet) { - mergedContext = (T) contextAccessor.restoreValues(this, mergedContext); - } - return mergedContext; - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public T saveTo(T context) { - ContextContainerPropagator propagator = ContextContainerPropagatorLoader.getPropagatorToSave(context); - return (T) propagator.save(this, context); + this.contextAccessors = Collections.unmodifiableList(new ArrayList<>(contextAccessors)); + this.threadLocalAccessors = Collections.unmodifiableList(new ArrayList<>(threadLocalAccessors)); } @Override @@ -90,6 +74,35 @@ public T remove(String key) { return (T) this.values.remove(key); } + @Override + public void captureValues(Object context) { + for (ContextAccessor accessor : getContextAccessors(context, true)) { + accessor.captureValues(context, this); + } + } + + @Override + public T restoreValues(T context) { + T mergedContext = context; + for (ContextAccessor accessor : getContextAccessors(context, false)) { + mergedContext = (T) accessor.restoreValues(this, mergedContext); + } + return mergedContext; + } + + private List getContextAccessors(Object context, boolean capture) { + List accessors = this.contextAccessorCache.get(context.getClass()); + if (accessors == null) { + accessors = this.contextAccessors.stream() + .filter(capture ? + accessor -> accessor.canCaptureFrom(context.getClass()) : + accessor -> accessor.canRestoreTo(context.getClass())) + .collect(Collectors.toList()); + this.contextAccessorCache.put(context.getClass(), accessors); + } + return accessors; + } + @Override public ContextContainer captureThreadLocalValues() { this.threadLocalAccessors.forEach(accessor -> accessor.captureValues(this)); @@ -99,14 +112,22 @@ public ContextContainer captureThreadLocalValues() { @Override public ContextContainer captureThreadLocalValues(Predicate predicate) { this.predicates.add(predicate); - this.threadLocalAccessors.stream().filter(t -> t.isApplicable(predicate)).forEach(accessor -> accessor.captureValues(this)); + for (ThreadLocalAccessor accessor : this.threadLocalAccessors) { + if (accessor.isApplicable(predicate)) { + accessor.captureValues(this); + } + } return this; } @Override public Scope restoreThreadLocalValues() { - List accessors = this.threadLocalAccessors.stream().filter(t -> this.predicates.stream().allMatch(p -> p.test(t.getNamespace()))) - .collect(Collectors.toList()); + List accessors = new ArrayList<>(); + for (ThreadLocalAccessor accessor : this.threadLocalAccessors) { + if (this.predicates.stream().allMatch(predicate -> predicate.test(accessor.getNamespace()))) { + accessors.add(accessor); + } + } accessors.forEach(accessor -> accessor.restoreValues(this)); return () -> { accessors.forEach(accessor -> accessor.resetValues(this)); @@ -115,8 +136,10 @@ public Scope restoreThreadLocalValues() { } @Override - public boolean isNoOp() { - return false; + @SuppressWarnings({"unchecked", "rawtypes"}) + public T saveTo(T context) { + ContextContainerAdapter adapter = ContextContainerAdapterLoader.getAdapterToWrite(context); + return (T) adapter.save(this, context); } /** diff --git a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ThreadLocalAccessorLoader.java b/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ThreadLocalAccessorLoader.java deleted file mode 100644 index 49946f3..0000000 --- a/context-propagation-api/src/main/java/io/micrometer/contextpropagation/ThreadLocalAccessorLoader.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed 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 - * - * https://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 io.micrometer.contextpropagation; - -import java.util.List; -import java.util.ServiceLoader; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -/** - * Loads {@link ThreadLocalAccessor}. - */ -final class ThreadLocalAccessorLoader { - - private static final ServiceLoader threadLocalAccessors = ServiceLoader.load(ThreadLocalAccessor.class); - - static List getThreadLocalAccessors() { - return StreamSupport.stream(threadLocalAccessors.spliterator(), false).collect(Collectors.toList()); - } - -} diff --git a/context-propagation-api/src/test/java/io/micrometer/contextpropagation/InstrumentationTests.java b/context-propagation-api/src/test/java/io/micrometer/contextpropagation/InstrumentationTests.java index 52e7722..c7d2af1 100644 --- a/context-propagation-api/src/test/java/io/micrometer/contextpropagation/InstrumentationTests.java +++ b/context-propagation-api/src/test/java/io/micrometer/contextpropagation/InstrumentationTests.java @@ -33,7 +33,8 @@ class InstrumentationTests { - ContextContainer container = ContextContainer.create(); + ContextContainer container = new DefaultContextContainer( + Collections.emptyList(), Collections.singletonList(new ObservationThreadLocalAccessor())); @AfterEach void clear() { diff --git a/context-propagation-api/src/test/java/io/micrometer/contextpropagation/SimpleThreadLocalAccessorTests.java b/context-propagation-api/src/test/java/io/micrometer/contextpropagation/SimpleThreadLocalAccessorTests.java index 63a3721..10fed78 100644 --- a/context-propagation-api/src/test/java/io/micrometer/contextpropagation/SimpleThreadLocalAccessorTests.java +++ b/context-propagation-api/src/test/java/io/micrometer/contextpropagation/SimpleThreadLocalAccessorTests.java @@ -15,13 +15,16 @@ */ package io.micrometer.contextpropagation; +import java.util.Collections; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.BDDAssertions.then; class SimpleThreadLocalAccessorTests { - ContextContainer container = ContextContainer.create(); + ContextContainer container = new DefaultContextContainer( + Collections.emptyList(), Collections.singletonList(new ObservationThreadLocalAccessor())); @Test void should_capture_thread_local_values() { diff --git a/context-propagation-api/src/test/resources/META-INF/services/io.micrometer.contextpropagation.ThreadLocalAccessor b/context-propagation-api/src/test/resources/META-INF/services/io.micrometer.contextpropagation.ThreadLocalAccessor deleted file mode 100644 index d4525d9..0000000 --- a/context-propagation-api/src/test/resources/META-INF/services/io.micrometer.contextpropagation.ThreadLocalAccessor +++ /dev/null @@ -1 +0,0 @@ -io.micrometer.contextpropagation.ObservationThreadLocalAccessor