diff --git a/context-propagation-api/README.md b/context-propagation-api/README.md index 00dbcf0b..fd61ef78 100644 --- a/context-propagation-api/README.md +++ b/context-propagation-api/README.md @@ -35,15 +35,15 @@ although technically these use cases are not appropriate. Manages contexts by initializing and maintaining an active context value. Normally it is not necessary to interact directly with individual context managers. -The `ContextManagers` utility class detects available context managers and lets -you take a [_snapshot_](#context-snapshot) of **all** active contexts at once. +The api detects available context managers and lets +you capture a [_snapshot_](#context-snapshot) of **all** active contexts at once. - [ContextManager javadoc][contextmanager] -- [ContextManagers javadoc][contextmanagers] +- [ContextSnapshot javadoc][contextsnapshot] ### Context Snapshot -A context snapshot is created by the [ContextManagers]' `createContextSnapshot()` method. +A context snapshot is captured by the [ContextSnapshot]' `capture()` method. The snapshot contains active context values from all known [ContextManager] implementations. Once created, the captured _values_ in such context snapshot will not change anymore, even when the active context is later modified. @@ -52,7 +52,6 @@ They stay active until the reactivation is closed again (or are overwritten by n Closing the reactivated object is mandatory (from the thread where the reactivation was called). - [ContextSnapshot javadoc](https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/ContextSnapshot.html) -- [ContextManagers javadoc](https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/ContextManagers.html) ## Creating your own context manager @@ -68,23 +67,24 @@ It should contain the fully qualified classname of your implementation. ```java public class DummyContextManager implements ContextManager { - public Context initializeNewContext(String value) { - return new DummyContext(value); + public Context initializeNewContext(String value) { + return new DummyContext(value); + } + + public Context getActiveContextValue() { + DummyContext current = DummyContext.current(); + return current != null ? current.getValue() : null; + } + + private static final class DummyContext extends AbstractThreadLocalContext { + private DummyContext(String newValue) { + super(newValue); } - public Context getActiveContext() { - return DummyContext.current(); - } - - private static final class DummyContext extends AbstractThreadLocalContext { - private DummyContext(String newValue) { - super(newValue); - } - - private static Context current() { - return AbstractThreadLocalContext.current(DummyContext.class); - } + private static Context current() { + return AbstractThreadLocalContext.current(DummyContext.class); } + } } ``` @@ -95,7 +95,6 @@ public class DummyContextManager implements ContextManager { [javadoc]: https://www.javadoc.io/doc/nl.talsmasoftware.context/context-propagation [threadlocal]: https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html - [context]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/Context.html - [contextsnapshot]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/ContextSnapshot.html - [contextmanager]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/ContextManager.html - [contextmanagers]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/ContextManagers.html + [context]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/api/Context.html + [contextsnapshot]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/api/ContextSnapshot.html + [contextmanager]: https://javadoc.io/page/nl.talsmasoftware.context/context-propagation/latest/nl/talsmasoftware/context/api/ContextManager.html diff --git a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/Context.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/Context.java index 7b333a5b..8e3b70d5 100644 --- a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/Context.java +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/Context.java @@ -46,6 +46,8 @@ */ public interface Context extends Closeable { + // TODO think about removing Context.getValue as ContextManager.getActiveContextValue() should suffice. + /** * The value associated with this context. * diff --git a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextManager.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextManager.java index dda2c843..ecd55a6c 100644 --- a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextManager.java +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextManager.java @@ -62,10 +62,62 @@ public interface ContextManager { * to clear all contexts before returning threads to the pool. * *

- * This method normally should only get called by {@code ContextManagers.clearActiveContexts()}. + * This method normally should only get called by {@linkplain #clearAll()}. * * @since 2.0.0 */ void clear(); + /** + * Clears all active contexts from the current thread. + * + *

+ * Contexts that are 'stacked' (i.e. restore the previous state upon close) + * should be closed in a way that includes all 'parent' contexts as well. + * + *

+ * This operation is not intended to be used by general application code + * as it likely breaks any 'stacked' active context that surrounding code may depend upon. + * + *

+ * Appropriate use includes thread management, where threads are reused by some pooling mechanism.
+ * For example, it is considered safe to clear the context when obtaining a 'fresh' thread from a + * thread pool (as no context expectations should exist at that point).
+ * An even better strategy would be to clear the context right before returning a used thread + * back to the pool as this will allow any unclosed contexts to be garbage collected.
+ * Besides preventing contextual issues, this reduces the risk of memory leaks by unbalanced context calls. + * + * @since 2.0.0 + */ + static void clearAll() { + ContextSnapshotImpl.clearActiveContexts(); + } + + /** + * Override the {@linkplain ClassLoader} used to lookup {@linkplain ContextManager context managers}. + * + *

+ * Normally, capturing a snapshot uses the {@linkplain Thread#getContextClassLoader() Context ClassLoader} from the + * {@linkplain Thread#currentThread() current thread} to look up all {@linkplain ContextManager context managers}. + * It is possible to configure a fixed, single classloader in your application for these lookups. + * + *

+ * Using this method to specify a fixed classloader will only impact + * new {@linkplain ContextSnapshot context snapshots}.
+ * Existing snapshots will not be impacted. + * + *

+ * Notes:
+ *

    + *
  • Please be aware that this configuration is global! + *
  • This will also affect the lookup of {@linkplain ContextTimer context timers} + *
+ * + * @param classLoader The single, fixed ClassLoader to use for finding context managers. + * Specify {@code null} to restore the default behaviour. + * @since 2.0.0 + */ + static void useClassLoader(ClassLoader classLoader) { + ServiceCache.useClassLoader(classLoader); + } } diff --git a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshot.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshot.java index 0c6da1a8..c9739ecb 100644 --- a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshot.java +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshot.java @@ -25,8 +25,7 @@ * ensuring that all context values are set in that other thread. * *

- * A snapshot can be obtained from the {@code ContextManagers} utility class for interaction with all registered - * {@link ContextManager} implementations. + * A snapshot can be obtained from the {@linkplain #capture()} method. * *

* This library contains several utility classes named {@code ContextAware...} or {...WithContext} that will @@ -41,6 +40,23 @@ * @since 2.0.0 */ public interface ContextSnapshot { + /** + * Captures a snapshot of the current + * {@link ContextManager#getActiveContextValue() active context value} + * from all known {@link ContextManager} implementations. + * + *

+ * This snapshot with context values is returned as a single object and can be temporarily + * {@link ContextSnapshot#reactivate() reactivated}. + * Remember to {@link Context#close() close} the reactivated context once you're done, + * preferably in a try-with-resources construct. + * + * @return A new context snapshot that can be reactivated elsewhere (e.g. a background thread) + * within a try-with-resources construct. + */ + static ContextSnapshot capture() { + return ContextSnapshotImpl.capture(); + } /** * Temporarily reactivates all captured context values that are in the snapshot. diff --git a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshotImpl.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshotImpl.java new file mode 100644 index 00000000..ef76a332 --- /dev/null +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextSnapshotImpl.java @@ -0,0 +1,236 @@ +/* + * Copyright 2016-2024 Talsma ICT + * + * 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 + * + * 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 nl.talsmasoftware.context.api; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +final class ContextSnapshotImpl implements ContextSnapshot { + private static final Logger SNAPSHOT_LOGGER = Logger.getLogger(ContextSnapshot.class.getName()); + private static final Logger MANAGER_LOGGER = Logger.getLogger(ContextManager.class.getName()); + private static final Logger TIMER_LOGGER = Logger.getLogger(ContextTimer.class.getName()); + + private final List managers; + private final Object[] values; + + static ContextSnapshot capture() { + final long start = System.nanoTime(); + RuntimeException error = null; + try { + return new ContextSnapshotImpl(); + } catch (RuntimeException e) { + SNAPSHOT_LOGGER.log(Level.FINEST, e, () -> "Error capturing ContextSnapshot from " + Thread.currentThread().getName() + ": " + e.getMessage()); + ServiceCache.clear(); + throw error = e; + } finally { + timed(System.nanoTime() - start, ContextSnapshot.class, "capture", error); + } + } + + private ContextSnapshotImpl() { + managers = ServiceCache.cached(ContextManager.class); // Cached list is immutable + values = new Object[managers.size()]; + for (int i = 0; i < values.length; i++) { + values[i] = getActiveContextValue(managers.get(i)); + } + if (managers.isEmpty() && SNAPSHOT_LOGGER.isLoggable(Level.FINER)) { + final Thread currentThread = Thread.currentThread(); + SNAPSHOT_LOGGER.finer(this + " was created but no context managers were found! Thread=" + + currentThread.getName() + ", ContextClassLoader=" + currentThread.getContextClassLoader()); + } + } + + public Reactivation reactivate() { + final long start = System.nanoTime(); + RuntimeException error = null; + final Context[] reactivatedContexts = new Context[managers.size()]; + try { + + for (int i = 0; i < values.length; i++) { + reactivatedContexts[i] = reactivate(managers.get(i), values[i]); + } + return new ReactivationImpl(reactivatedContexts); + + } catch (RuntimeException reactivationException) { + tryClose(reactivatedContexts, reactivationException); + ServiceCache.clear(); + throw error = reactivationException; + } finally { + timed(System.nanoTime() - start, ContextSnapshot.class, "reactivate", error); + } + } + + @Override + public String toString() { + return "ContextSnapshot{size=" + managers.size() + '}'; + } + + /** + * Clears all active contexts from the current thread. + * + *

+ * Contexts that are 'stacked' (i.e. restore the previous state upon close) should be + * closed in a way that includes all 'parent' contexts as well. + * + *

+ * This operation is not intended to be used by general application code as it likely breaks any 'stacked' + * active context that surrounding code may depend upon. + * Appropriate use includes thread management, where threads are reused by some pooling + * mechanism. For example, it is considered safe to clear the context when obtaining a 'fresh' thread from a + * thread pool (as no context expectations should exist at that point). + * An even better strategy would be to clear the context right before returning a used thread to the pool + * as this will allow any unclosed contexts to be garbage collected. Besides preventing contextual issues, + * this reduces the risk of memory leaks by unbalanced context calls. + */ + static void clearActiveContexts() { + final long start = System.nanoTime(); + for (ContextManager manager : ServiceCache.cached(ContextManager.class)) { + clear(manager); + } + timed(System.nanoTime() - start, Context.class, "clearAll", null); + } + + /** + * Implementation of the reactivated 'container' context that closes all reactivated contexts + * when it is closed itself.
+ * This context contains no meaningful value in itself and purely exists to close the reactivated contexts. + */ + @SuppressWarnings("rawtypes") + private static final class ReactivationImpl implements Reactivation { + private final Context[] reactivated; + + private ReactivationImpl(Context[] reactivated) { + this.reactivated = reactivated; + } + + public void close() { + RuntimeException closeException = null; + // close in reverse order of reactivation + for (int i = reactivated.length - 1; i >= 0; i--) { + if (reactivated[i] != null) { + try { + reactivated[i].close(); + } catch (RuntimeException rte) { + if (closeException == null) closeException = rte; + else closeException.addSuppressed(rte); + } + } + } + if (closeException != null) { + throw closeException; + } + } + + @Override + public String toString() { + return "ContextSnapshot.Reactivation{size=" + reactivated.length + '}'; + } + } + + private static Object getActiveContextValue(final ContextManager manager) { + final long start = System.nanoTime(); + RuntimeException error = null; + try { + + final Object activeContextValue = manager.getActiveContextValue(); + SNAPSHOT_LOGGER.finest(() -> activeContextValue == null + ? "There is no active context value for " + manager + " (in thread " + Thread.currentThread().getName() + ")." + : "Active context value of " + manager + " in " + Thread.currentThread().getName() + ": " + activeContextValue); + return activeContextValue; + + } catch (RuntimeException e) { + SNAPSHOT_LOGGER.log(Level.WARNING, e, () -> "Error obtaining active context from " + manager + " (in thread " + Thread.currentThread().getName() + ")."); + error = e; + return null; + } finally { + timed(System.nanoTime() - start, manager.getClass(), "getActiveContextValue", error); + } + } + + private static void clear(ContextManager manager) { + final long start = System.nanoTime(); + RuntimeException error = null; + try { + + manager.clear(); + MANAGER_LOGGER.finest(() -> "Active context of " + manager + " was cleared."); + + } catch (RuntimeException e) { + MANAGER_LOGGER.log(Level.WARNING, e, () -> "Error clearing active context from " + manager + "(in thread " + Thread.currentThread().getName() + ")."); + error = e; + } finally { + timed(System.nanoTime() - start, manager.getClass(), "clear", error); + } + } + + /** + * Reactivates a snapshot value for a single context manager. + * + *

+ * This initializes a new context with the context manager + * (normally on another thread the snapshot value was captured from). + * + * @param contextManager The context manager to reactivate the snapshot value for. + * @param snapshotValue The snapshot value to be reactivated. + * @return The context to be included in the reactivation object. + */ + @SuppressWarnings("unchecked") // We got the value from the managers itself. + private static Context reactivate(ContextManager contextManager, Object snapshotValue) { + if (snapshotValue == null) return null; + long start = System.nanoTime(); + RuntimeException error = null; + try { + + Context reactivated = contextManager.initializeNewContext(snapshotValue); + SNAPSHOT_LOGGER.finest(() -> "Context reactivated from snapshot by " + contextManager + ": " + reactivated + "."); + return reactivated; + + } catch (RuntimeException e) { + throw error = e; + } finally { + timed(System.nanoTime() - start, contextManager.getClass(), "initializeNewContext", error); + } + } + + /** + * Try to close already-reactivated contexts when a later context manager threw an exception. + * + * @param reactivatedContexts The contexts that were already reactivated when the error happened. + * @param reason The error that happened. + */ + private static void tryClose(Context[] reactivatedContexts, Throwable reason) { + for (Context alreadyReactivated : reactivatedContexts) { + if (alreadyReactivated != null) { + try { + alreadyReactivated.close(); + } catch (RuntimeException rte) { + reason.addSuppressed(rte); + } + } + } + } + + private static void timed(long durationNanos, Class type, String method, Throwable error) { + for (ContextTimer delegate : ServiceCache.cached(ContextTimer.class)) { + delegate.update(type, method, durationNanos, TimeUnit.NANOSECONDS, error); + } + if (TIMER_LOGGER.isLoggable(Level.FINEST)) { + TIMER_LOGGER.log(Level.FINEST, "{0}.{1}: {2,number}ns", new Object[]{type.getName(), method, durationNanos}); + } + } +} diff --git a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextTimer.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextTimer.java index 7f106309..8fa91903 100644 --- a/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextTimer.java +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ContextTimer.java @@ -22,7 +22,7 @@ *

* Currently, the following timed operations are updated: *

    - *
  • {@code ContextManagers.createContextSnapshot}
  • + *
  • {@linkplain ContextSnapshot#capture()}
  • *
  • {@linkplain ContextSnapshot#reactivate()}
  • *
  • {@linkplain ContextManager#getActiveContextValue()} (*)
  • *
  • {@linkplain ContextManager#initializeNewContext(Object)} (*)
  • diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ServiceCache.java b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ServiceCache.java similarity index 93% rename from context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ServiceCache.java rename to context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ServiceCache.java index 18d8122d..09b0d067 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ServiceCache.java +++ b/context-propagation-api/src/main/java/nl/talsmasoftware/context/api/ServiceCache.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.talsmasoftware.context.core; +package nl.talsmasoftware.context.api; import java.util.ArrayList; import java.util.Collections; @@ -27,9 +27,12 @@ * Cache for resolved services. * *

    - * This is required because the ServiceLoader itself is not thread-safe due to its internal lazy iterator. + * This is necessary because the ServiceLoader itself is not thread-safe due to its internal lazy iterator. + * + *

    + * Only intended for interal use. */ -class ServiceCache { +final class ServiceCache { private static final Logger LOGGER = Logger.getLogger(ServiceCache.class.getName()); /** diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextManagersTest.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/api/ContextSnapshotTest.java similarity index 55% rename from context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextManagersTest.java rename to context-propagation-api/src/test/java/nl/talsmasoftware/context/api/ContextSnapshotTest.java index f83d882a..3bcef624 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextManagersTest.java +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/api/ContextSnapshotTest.java @@ -13,73 +13,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.talsmasoftware.context.core; +package nl.talsmasoftware.context.api; -import nl.talsmasoftware.context.api.Context; -import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import nl.talsmasoftware.context.dummy.DummyContext; import nl.talsmasoftware.context.dummy.DummyContextManager; +import nl.talsmasoftware.context.dummy.DummyContextTimer; import nl.talsmasoftware.context.dummy.ThrowingContextManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; /** * @author Sjoerd Talsma */ -public class ContextManagersTest { +class ContextSnapshotTest { DummyContextManager dummyManager = new DummyContextManager(); @BeforeEach @AfterEach - public void resetContexts() { - ContextManagers.clearActiveContexts(); + void resetContexts() { + ContextManager.clearAll(); + DummyContextTimer.clear(); } @BeforeEach @AfterEach - public void resetContextClassLoader() { - ContextManagers.useClassLoader(null); + void resetContextClassLoader() { + ContextManager.useClassLoader(null); } @Test - public void testUnsupportedConstructor() { - Constructor[] constructors = ContextManagers.class.getDeclaredConstructors(); - assertThat("Number of constructors", constructors.length, is(1)); - assertThat("Constructor parameters", constructors[0].getParameterTypes().length, is(0)); - assertThat("Constructor accessibility", constructors[0].isAccessible(), is(false)); - try { - constructors[0].setAccessible(true); - constructors[0].newInstance(); - fail("Exception expected."); - } catch (IllegalAccessException | InstantiationException e) { - fail("InvocationTargetException expected."); - } catch (InvocationTargetException e) { - assertThat(e.getCause(), is(instanceOf(UnsupportedOperationException.class))); - } - } - - @Test - public void testSnapshot_inSameThread() { + void testSnapshot_inSameThread() { dummyManager.clear(); assertThat(DummyContext.currentValue(), is(nullValue())); @@ -89,7 +68,7 @@ public void testSnapshot_inSameThread() { DummyContext ctx2 = new DummyContext("second value"); assertThat(DummyContext.currentValue(), is("second value")); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat(DummyContext.currentValue(), is("second value")); // No context change because of snapshot. DummyContext ctx3 = new DummyContext("third value"); @@ -116,64 +95,28 @@ public void testSnapshot_inSameThread() { } @Test - public void testSnapshotThreadPropagation() throws ExecutionException, InterruptedException { - DummyContext.reset(); - ExecutorService threadpool = new ContextAwareExecutorService(Executors.newCachedThreadPool()); - assertThat(DummyContext.currentValue(), is(nullValue())); - - DummyContext ctx1 = new DummyContext("initial value"); - assertThat(DummyContext.currentValue(), is("initial value")); - Future threadResult = threadpool.submit(new Callable() { - public String call() throws Exception { - return DummyContext.currentValue(); - } - }); - assertThat(threadResult.get(), is("initial value")); - - DummyContext ctx2 = new DummyContext("second value"); - threadResult = threadpool.submit(new Callable() { - public String call() throws Exception { - String res = DummyContext.currentValue(); - try (DummyContext inThread = new DummyContext("in-thread value")) { - res += ", " + DummyContext.currentValue(); - } - return res + ", " + DummyContext.currentValue(); - } - }); - assertThat(DummyContext.currentValue(), is("second value")); - assertThat(threadResult.get(), is("second value, in-thread value, second value")); - - ctx2.close(); - ctx1.close(); - } - - @Test - public void testConcurrentSnapshots() throws ExecutionException, InterruptedException { - int threadcount = 25; - ExecutorService threadpool = Executors.newFixedThreadPool(threadcount); + void testConcurrentSnapshots() throws ExecutionException, InterruptedException { + int threadCount = 25; + ExecutorService threadPool = Executors.newFixedThreadPool(threadCount); try { - List> snapshots = new ArrayList>(threadcount); - for (int i = 0; i < threadcount; i++) { - snapshots.add(threadpool.submit(new Callable() { - public ContextSnapshot call() throws Exception { - return ContextManagers.createContextSnapshot(); - } - })); + List> snapshots = new ArrayList<>(threadCount); + for (int i = 0; i < threadCount; i++) { + snapshots.add(threadPool.submit(ContextSnapshot::capture)); } - for (int i = 0; i < threadcount; i++) { + for (int i = 0; i < threadCount; i++) { assertThat(snapshots.get(i).get(), is(notNullValue())); } } finally { - threadpool.shutdown(); + threadPool.shutdown(); } } @Test - public void testCreateSnapshot_ExceptionHandling() { + void testCreateSnapshot_ExceptionHandling() { ThrowingContextManager.onGet = new IllegalStateException("No active context!"); Context ctx = new DummyContext("blah"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); ctx.close(); assertThat(DummyContext.currentValue(), is(nullValue())); @@ -184,12 +127,12 @@ public void testCreateSnapshot_ExceptionHandling() { } @Test - public void testReactivateSnapshot_ExceptionHandling() { + void testReactivateSnapshot_ExceptionHandling() { final RuntimeException reactivationException = new IllegalStateException("Cannot create new context!"); ThrowingContextManager mgr = new ThrowingContextManager(); Context ctx1 = new DummyContext("foo"); Context ctx2 = mgr.initializeNewContext("bar"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); ThrowingContextManager.onInitialize = reactivationException; assertThat(DummyContext.currentValue(), is("foo")); @@ -207,14 +150,14 @@ public void testReactivateSnapshot_ExceptionHandling() { } @Test - public void testConcurrentSnapshots_fixedClassLoader() throws ExecutionException, InterruptedException { - ContextManagers.useClassLoader(Thread.currentThread().getContextClassLoader()); + void testConcurrentSnapshots_fixedClassLoader() throws ExecutionException, InterruptedException { + ContextManager.useClassLoader(Thread.currentThread().getContextClassLoader()); int threadcount = 25; ExecutorService threadpool = Executors.newFixedThreadPool(threadcount); try { Future[] snapshots = new Future[threadcount]; for (int i = 0; i < threadcount; i++) { - snapshots[i] = threadpool.submit(ContextManagers::createContextSnapshot); + snapshots[i] = threadpool.submit(ContextSnapshot::capture); } for (int i = 0; i < threadcount; i++) { @@ -226,4 +169,26 @@ public void testConcurrentSnapshots_fixedClassLoader() throws ExecutionException } } + @Test + void toString_isForSnapshot_notSnapshotImpl() { + assertThat(ContextSnapshot.capture(), hasToString(containsString("ContextSnapshot{"))); + } + + @Test + void testTimingDelegation() { + DummyContextTimer.clear(); + assertThat(DummyContextTimer.getLastTimedMillis(ContextSnapshot.class, "capture"), nullValue()); + assertThat(DummyContextTimer.getLastTimedMillis(ContextSnapshot.class, "reactivate"), nullValue()); + + ContextSnapshot.capture().reactivate().close(); + assertThat(DummyContextTimer.getLastTimedMillis(ContextSnapshot.class, "capture"), notNullValue()); + assertThat(DummyContextTimer.getLastTimedMillis(ContextSnapshot.class, "reactivate"), notNullValue()); + } + + @Test + void testReactivationToString() { + try (ContextSnapshot.Reactivation reactivation = ContextSnapshot.capture().reactivate()) { + assertThat(reactivation, hasToString(containsString("ContextSnapshot.Reactivation{"))); + } + } } diff --git a/context-propagation-api/src/test/java/nl/talsmasoftware/context/api/NoContextManagersTest.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/api/NoContextManagersTest.java new file mode 100644 index 00000000..34c946a6 --- /dev/null +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/api/NoContextManagersTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016-2024 Talsma ICT + * + * 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 + * + * 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 nl.talsmasoftware.context.api; + +import nl.talsmasoftware.context.dummy.DummyContext; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +public class NoContextManagersTest { + private static final String SERVICE_LOCATION = "target/test-classes/META-INF/services/"; + private static final File SERVICE_FILE = new File(SERVICE_LOCATION + ContextManager.class.getName()); + private static final File TMP_SERVICE_FILE = new File(SERVICE_LOCATION + "tmp-ContextManager"); + + @BeforeEach + public void avoidContextManagersCache() { + ContextManager.useClassLoader(new ClassLoader(Thread.currentThread().getContextClassLoader()) { + }); + assertThat("Move service file", SERVICE_FILE.renameTo(TMP_SERVICE_FILE), is(true)); + } + + @AfterEach + public void resetDefaultClassLoader() { + ContextManager.useClassLoader(null); + assertThat("Restore service file!", TMP_SERVICE_FILE.renameTo(SERVICE_FILE), is(true)); + } + + @Test + public void testReactivate_withoutContextManagers() { + Context ctx1 = new DummyContext("foo"); + ContextSnapshot snapshot = ContextSnapshot.capture(); + ctx1.close(); + + ContextSnapshot.Reactivation reactivated = snapshot.reactivate(); + reactivated.close(); + } + + @Test + public void testCreateSnapshot_withoutContextManagers() { + ContextSnapshot snapshot = ContextSnapshot.capture(); + assertThat(snapshot, is(notNullValue())); + + ContextSnapshot.Reactivation reactivated = snapshot.reactivate(); + assertThat(reactivated, is(notNullValue())); + reactivated.close(); + } + + @Test + public void testClearManagedContexts_withoutContextManagers() { + Assertions.assertDoesNotThrow(() -> ContextManager.clearAll()); // there should be no exception + } + +} diff --git a/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContext.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContext.java new file mode 100644 index 00000000..c84479b0 --- /dev/null +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContext.java @@ -0,0 +1,75 @@ +/* + * Copyright 2016-2024 Talsma ICT + * + * 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 + * + * 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 nl.talsmasoftware.context.dummy; + +import nl.talsmasoftware.context.api.Context; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author Sjoerd Talsma + */ +public final class DummyContext implements Context { + private static final ThreadLocal INSTANCE = new ThreadLocal<>(); + + private final DummyContext parent; + private final String value; + private final AtomicBoolean closed; + + public DummyContext(String newValue) { + this.parent = INSTANCE.get(); + this.value = newValue; + this.closed = new AtomicBoolean(false); + INSTANCE.set(this); + } + + // Public for testing! + public boolean isClosed() { + return closed.get(); + } + + public String getValue() { + return value; + } + + public void close() { + if (closed.compareAndSet(false, true) && INSTANCE.get() == this) { + DummyContext current = INSTANCE.get(); + while (current != null && current.isClosed()) { + current = current.parent; + } + if (current == null) { + INSTANCE.remove(); + } else { + INSTANCE.set(current); + } + } + } + + public static String currentValue() { + final Context currentContext = INSTANCE.get(); + return currentContext != null ? currentContext.getValue() : null; + } + + public static void setCurrentValue(String value) { + new DummyContext(value); + } + + public static void reset() { + INSTANCE.remove(); + } + +} diff --git a/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextManager.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextManager.java new file mode 100644 index 00000000..f1b766bf --- /dev/null +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextManager.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016-2024 Talsma ICT + * + * 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 + * + * 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 nl.talsmasoftware.context.dummy; + +import nl.talsmasoftware.context.api.Context; +import nl.talsmasoftware.context.api.ContextManager; + +/** + * Trivial manager around the {@link DummyContext} implementation to be registered as service provider. + * + * @author Sjoerd Talsma + */ +public class DummyContextManager implements ContextManager { + + public Context initializeNewContext(String value) { + return new DummyContext(value); + } + + public String getActiveContextValue() { + return DummyContext.currentValue(); + } + + public void clear() { + DummyContext.reset(); + } + + public static void clearAllContexts() { + DummyContext.reset(); + } + + @Override + public int hashCode() { + return DummyContextManager.class.hashCode(); + } + + @Override + public boolean equals(Object other) { + return this == other || other instanceof DummyContextManager; + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/Timers.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextTimer.java similarity index 51% rename from context-propagation-core/src/main/java/nl/talsmasoftware/context/core/Timers.java rename to context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextTimer.java index 0ec1366e..5cd9bd96 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/Timers.java +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/DummyContextTimer.java @@ -13,24 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package nl.talsmasoftware.context.core; +package nl.talsmasoftware.context.dummy; import nl.talsmasoftware.context.api.ContextTimer; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -final class Timers { - private static final Logger TIMING_LOGGER = Logger.getLogger(Timers.class.getName()); +public class DummyContextTimer implements ContextTimer { + private static final Map LAST_TIMED = new HashMap(); - static void timed(long durationNanos, Class type, String method, Throwable error) { - for (ContextTimer delegate : ServiceCache.cached(ContextTimer.class)) { - delegate.update(type, method, durationNanos, TimeUnit.NANOSECONDS, error); - } - if (TIMING_LOGGER.isLoggable(Level.FINEST)) { - TIMING_LOGGER.log(Level.FINEST, "{0}.{1}: {2,number}ns", new Object[]{type.getName(), method, durationNanos}); - } + public static Long getLastTimedMillis(Class type, String method) { + return LAST_TIMED.get(type.getName() + "." + method); } + public void update(Class type, String method, long duration, TimeUnit unit, Throwable error) { + LAST_TIMED.put(type.getName() + "." + method, unit.toMillis(duration)); + } + + public static void clear() { + LAST_TIMED.clear(); + } } diff --git a/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/ThrowingContextManager.java b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/ThrowingContextManager.java new file mode 100644 index 00000000..d830737d --- /dev/null +++ b/context-propagation-api/src/test/java/nl/talsmasoftware/context/dummy/ThrowingContextManager.java @@ -0,0 +1,122 @@ +/* + * Copyright 2016-2024 Talsma ICT + * + * 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 + * + * 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 nl.talsmasoftware.context.dummy; + +import nl.talsmasoftware.context.api.Context; +import nl.talsmasoftware.context.api.ContextManager; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Badly behaved {@link ContextManager} implementation that can throw things at us for testing purposes. + * + * @author Sjoerd Talsma + */ +public class ThrowingContextManager implements ContextManager { + public static RuntimeException inConstructor = null, onInitialize = null, onGet = null, onClose = null, onClear = null; + + public ThrowingContextManager() { + if (inConstructor != null) try { + throw inConstructor; + } finally { + inConstructor = null; + } + } + + @Override + public Context initializeNewContext(String value) { + if (onInitialize != null) try { + throw onInitialize; + } finally { + onInitialize = null; + } + return new Ctx(value); + } + + @Override + public String getActiveContextValue() { + if (onGet != null) try { + throw onGet; + } finally { + onGet = null; + } + return Ctx.currentValue(); + } + + @Override + public void clear() { + if (onClear != null) try { + throw onClear; + } finally { + onClear = null; + } + Ctx.remove(); + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } + + private final static class Ctx implements Context { + private static final ThreadLocal STORAGE = new ThreadLocal<>(); + + private final Ctx parent; + private final String value; + private final AtomicBoolean closed; + + private Ctx(String newValue) { + parent = STORAGE.get(); + value = newValue; + closed = new AtomicBoolean(false); + STORAGE.set(this); + } + + @Override + public String getValue() { + return value; + } + + @Override + public void close() { + if (onClose != null) try { + throw onClose; + } finally { + onClose = null; + } + if (closed.compareAndSet(false, true) && STORAGE.get() == this) { + Ctx current = STORAGE.get(); + while (current != null && current.closed.get()) { + current = current.parent; + } + if (current == null) { + STORAGE.remove(); + } else { + STORAGE.set(current); + } + } + } + + private static String currentValue() { + Ctx current = STORAGE.get(); + return current != null ? current.getValue() : null; + } + + private static void remove() { + STORAGE.remove(); + } + } +} diff --git a/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextManager b/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextManager new file mode 100644 index 00000000..08742947 --- /dev/null +++ b/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextManager @@ -0,0 +1,2 @@ +nl.talsmasoftware.context.dummy.DummyContextManager +nl.talsmasoftware.context.dummy.ThrowingContextManager diff --git a/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer b/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer new file mode 100644 index 00000000..c1fe1c4a --- /dev/null +++ b/context-propagation-api/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer @@ -0,0 +1 @@ +nl.talsmasoftware.context.dummy.DummyContextTimer diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ContextManagers.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ContextManagers.java deleted file mode 100644 index 7fa293ae..00000000 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/ContextManagers.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2016-2024 Talsma ICT - * - * 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 - * - * 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 nl.talsmasoftware.context.core; - -import nl.talsmasoftware.context.api.Context; -import nl.talsmasoftware.context.api.ContextManager; -import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.api.ContextSnapshot.Reactivation; - -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Core implementation to allow {@link #createContextSnapshot() taking a snapshot of all contexts}. - * - *

    - * Such a {@link ContextSnapshot snapshot} can be passed to a background task to allow the context to be - * {@link ContextSnapshot#reactivate() reactivated} in that background thread, until it gets - * {@link Context#close() closed} again (preferably in a try-with-resources construct). - * - * @author Sjoerd Talsma - * @since 1.1.0 - */ -public final class ContextManagers { - private static final Logger LOGGER = Logger.getLogger(ContextManagers.class.getName()); - - /** - * Private constructor to avoid instantiation of this class. - */ - private ContextManagers() { - throw new UnsupportedOperationException(); - } - - /** - * This method is able to create a 'snapshot' from the current - * {@link ContextManager#getActiveContextValue() active context value} - * from all known {@link ContextManager} implementations. - * - *

    - * This snapshot is returned as a single object that can be temporarily - * {@link ContextSnapshot#reactivate() reactivated}. Don't forget to {@link Context#close() close} the reactivated - * context once you're done, preferably in a try-with-resources construct. - * - * @return A new snapshot that can be reactivated elsewhere (e.g. a background thread) - * within a try-with-resources construct. - */ - @SuppressWarnings("rawtypes") - public static ContextSnapshot createContextSnapshot() { - final long start = System.nanoTime(); - final List managers = ServiceCache.cached(ContextManager.class); // Cached list is immutable - final Object[] values = new Object[managers.size()]; - - for (int i = 0; i < values.length; i++) { - values[i] = getActiveContextValue(managers.get(i)); - } - - final ContextSnapshotImpl result = new ContextSnapshotImpl(managers, values); - if (managers.isEmpty() && LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer(result + " was created but no ContextManagers were found! " - + " Thread=" + Thread.currentThread() - + ", ContextClassLoader=" + Thread.currentThread().getContextClassLoader()); - } - Timers.timed(System.nanoTime() - start, ContextManagers.class, "createContextSnapshot", null); - return result; - } - - /** - * Clears all active contexts from the current thread. - * - *

    - * Contexts that are 'stacked' (i.e. restore the previous state upon close) should be - * closed in a way that includes all 'parent' contexts as well. - * - *

    - * This operation is not intended to be used by general application code as it likely breaks any 'stacked' - * active context that surrounding code may depend upon. - * Appropriate use includes thread management, where threads are reused by some pooling - * mechanism. For example, it is considered safe to clear the context when obtaining a 'fresh' thread from a - * thread pool (as no context expectations should exist at that point). - * An even better strategy would be to clear the context right before returning a used thread to the pool - * as this will allow any unclosed contexts to be garbage collected. Besides preventing contextual issues, - * this reduces the risk of memory leaks by unbalanced context calls. - */ - public static void clearActiveContexts() { - final long start = System.nanoTime(); - for (ContextManager manager : ServiceCache.cached(ContextManager.class)) { - clear(manager); - } - Timers.timed(System.nanoTime() - start, ContextManagers.class, "clearActiveContexts", null); - } - - /** - * Override the {@linkplain ClassLoader} used to lookup {@linkplain ContextManager contextmanagers}. - *

    - * Normally, taking a snapshot uses the {@linkplain Thread#getContextClassLoader() Context ClassLoader} from the - * {@linkplain Thread#currentThread() current thread} to look up all {@linkplain ContextManager context managers}. - * It is possible to configure a fixed, single classloader in your application for looking up the context managers. - *

    - * Using this method to specify a fixed classloader will only impact - * new {@linkplain ContextSnapshot context snapshots}. Existing snapshots will not be impacted. - *

    - * Notes:
    - *

      - *
    • Please be aware that this configuration is global! - *
    • This will also affect the lookup of - * {@linkplain nl.talsmasoftware.context.api.ContextTimer context timers} - *
    - * - * @param classLoader The single, fixed ClassLoader to use for finding context managers. - * Specify {@code null} to restore the default behaviour. - * @since 1.0.5 - */ - public static synchronized void useClassLoader(ClassLoader classLoader) { - ServiceCache.useClassLoader(classLoader); - } - - private static Object getActiveContextValue(ContextManager manager) { - final long start = System.nanoTime(); - RuntimeException error = null; - try { - - final Object activeContextValue = manager.getActiveContextValue(); - LOGGER.finest(() -> activeContextValue == null - ? "There is no active context value for " + manager + " (in thread " + Thread.currentThread().getName() + ")." - : "Active context value of " + manager + " in " + Thread.currentThread().getName() + ": " + activeContextValue); - return activeContextValue; - - } catch (RuntimeException e) { - LOGGER.log(Level.WARNING, e, () -> "Error obtaining active context from " + manager + " (in thread " + Thread.currentThread().getName() + ")."); - error = e; - return null; - } finally { - Timers.timed(System.nanoTime() - start, manager.getClass(), "getActiveContextValue", error); - } - } - - private static void clear(ContextManager manager) { - final long start = System.nanoTime(); - RuntimeException error = null; - try { - - manager.clear(); - LOGGER.finest(() -> "Active context of " + manager + " was cleared."); - - } catch (RuntimeException e) { - LOGGER.log(Level.WARNING, e, () -> "Error clearing active context from " + manager + "(in thread " + Thread.currentThread().getName() + ")."); - error = e; - } finally { - Timers.timed(System.nanoTime() - start, manager.getClass(), "clear", error); - } - } - - /** - * Implementation of the createContextSnapshot functionality that can reactivate all values from the - * snapshot in each corresponding {@link ContextManager}. - */ - @SuppressWarnings("rawtypes") - private static final class ContextSnapshotImpl implements ContextSnapshot { - private final List managers; - private final Object[] values; - - private ContextSnapshotImpl(List managers, Object[] values) { - this.managers = managers; - this.values = values; - } - - public Reactivation reactivate() { - final long start = System.nanoTime(); - RuntimeException error = null; - final Context[] reactivatedContexts = new Context[managers.size()]; - try { - - for (int i = 0; i < values.length; i++) { - reactivatedContexts[i] = reactivate(managers.get(i), values[i]); - } - return new ReactivationImpl(reactivatedContexts); - - } catch (RuntimeException reactivationException) { - tryClose(reactivatedContexts, reactivationException); - ServiceCache.clear(); - throw error = reactivationException; - } finally { - Timers.timed(System.nanoTime() - start, ContextSnapshot.class, "reactivate", error); - } - } - - @Override - public String toString() { - return "ContextSnapshot{size=" + managers.size() + '}'; - } - - /** - * Reactivates a snapshot value for a single context manager. - * - *

    - * This initializes a new context with the context manager - * (normally on another thread the snapshot value was captured from). - * - * @param contextManager The context manager to reactivate the snapshot value for. - * @param snapshotValue The snapshot value to be reactivated. - * @return The context to be included in the reactivation object. - */ - @SuppressWarnings("unchecked") // We got the value from the managers itself. - private static Context reactivate(ContextManager contextManager, Object snapshotValue) { - if (snapshotValue == null) return null; - long start = System.nanoTime(); - RuntimeException error = null; - try { - - Context reactivated = contextManager.initializeNewContext(snapshotValue); - LOGGER.finest(() -> "Context reactivated from snapshot by " + contextManager + ": " + reactivated + "."); - return reactivated; - - } catch (RuntimeException e) { - throw error = e; - } finally { - Timers.timed(System.nanoTime() - start, contextManager.getClass(), "initializeNewContext", error); - } - } - - /** - * Try to close already-reactivated contexts when a later context manager threw an exception. - * - * @param reactivatedContexts The contexts that were already reactivated when the error happened. - * @param reason The error that happened. - */ - private static void tryClose(Context[] reactivatedContexts, Throwable reason) { - for (Context alreadyReactivated : reactivatedContexts) { - if (alreadyReactivated != null) { - try { - alreadyReactivated.close(); - } catch (RuntimeException rte) { - reason.addSuppressed(rte); - } - } - } - } - } - - /** - * Implementation of the reactivated 'container' context that closes all reactivated contexts - * when it is closed itself.
    - * This context contains no meaningful value in itself and purely exists to close the reactivated contexts. - */ - @SuppressWarnings("rawtypes") - private static final class ReactivationImpl implements Reactivation { - private final Context[] reactivated; - - private ReactivationImpl(Context[] reactivated) { - this.reactivated = reactivated; - } - - public void close() { - RuntimeException closeException = null; - // close in reverse order of reactivation - for (int i = this.reactivated.length - 1; i >= 0; i--) { - Context reactivated = this.reactivated[i]; - if (reactivated != null) try { - reactivated.close(); - } catch (RuntimeException rte) { - if (closeException == null) closeException = rte; - else closeException.addSuppressed(rte); - } - } - if (closeException != null) throw closeException; - } - - @Override - public String toString() { - return "ContextSnapshot.Reactivation{size=" + reactivated.length + '}'; - } - } -} diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFuture.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFuture.java index c66d233f..4db10d33 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFuture.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFuture.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.concurrent; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.core.function.BiConsumerWithContext; import nl.talsmasoftware.context.core.function.BiFunctionWithContext; import nl.talsmasoftware.context.core.function.ConsumerWithContext; @@ -61,10 +60,10 @@ public class ContextAwareCompletableFuture extends CompletableFuture { private final boolean takeNewSnapshot; /** - * Creates a new {@link ContextSnapshot} and remembers that in this completable future, + * Captures a new {@link ContextSnapshot} and remembers that in this completable future, * running all completion methods within this snapshot. * - * @see ContextManagers#createContextSnapshot() + * @see ContextSnapshot#capture() */ public ContextAwareCompletableFuture() { this((ContextSnapshot) null); @@ -75,8 +74,8 @@ public ContextAwareCompletableFuture() { * snapshot context. * * @param snapshot the snapshot to run completion methods in. - * Optional, the completable future will take a new snaphot if {@code null} is provided. - * @see ContextManagers#createContextSnapshot() + * Optional, the completable future will capture a new snapshot if {@code null} is provided. + * @see ContextSnapshot#capture() */ public ContextAwareCompletableFuture(ContextSnapshot snapshot) { this(new ContextSnapshotHolder(snapshot), false); @@ -126,8 +125,8 @@ public static ContextAwareCompletableFuture supplyAsync(Supplier suppl * This method is lenient to {@code null} values for {@code executor} and {@code snapshot}:
    * If {@code executor == null} the common {@link java.util.concurrent.ForkJoinPool ForkJoinPool} is used as * specified by {@link CompletableFuture#supplyAsync(Supplier)}.
    - * If {@code snapshot == null} a {@link ContextManagers#createContextSnapshot() new context snapshot} is - * created for the {@link Supplier} (if not already a {@link SupplierWithContext}). + * If {@code snapshot == null} a {@link ContextSnapshot#capture() new context snapshot} is + * captured for the {@link Supplier} (if not already a {@link SupplierWithContext}). * * @param supplier a function returning the value to be used to complete the returned CompletableFuture * @param executor the executor to use for asynchronous execution @@ -150,8 +149,8 @@ public static ContextAwareCompletableFuture supplyAsync(Supplier suppl * This method is lenient to {@code null} values for {@code executor} and {@code snapshot}:
    * If {@code executor == null} the common {@link java.util.concurrent.ForkJoinPool ForkJoinPool} is used as * specified by {@link CompletableFuture#supplyAsync(Supplier)}.
    - * If {@code snapshot == null} a {@link ContextManagers#createContextSnapshot() new context snapshot} is - * created for the {@link Supplier} (if not already a {@link SupplierWithContext}). + * If {@code snapshot == null} a {@link ContextSnapshot#capture() new context snapshot} is + * captured for the {@link Supplier} (if not already a {@link SupplierWithContext}). * * @param supplier a function returning the value to be used to complete the returned CompletableFuture * @param executor the executor to use for asynchronous execution @@ -215,8 +214,8 @@ public static ContextAwareCompletableFuture runAsync(Runnable runnable, Ex * This method is lenient to {@code null} values for {@code executor} and {@code snapshot}:
    * If {@code executor == null} the common {@link java.util.concurrent.ForkJoinPool ForkJoinPool} is used as * specified by {@link CompletableFuture#supplyAsync(Supplier)}.
    - * If {@code snapshot == null} a {@link ContextManagers#createContextSnapshot() new context snapshot} is - * created for the {@link Supplier} (if not already a {@link SupplierWithContext}). + * If {@code snapshot == null} a {@link ContextSnapshot#capture() new context snapshot} is + * captured for the {@link Supplier} (if not already a {@link SupplierWithContext}). * * @param runnable the action to run before completing the returned CompletableFuture * @param executor the executor to use for asynchronous execution @@ -237,8 +236,8 @@ public static ContextAwareCompletableFuture runAsync(Runnable runnable, Ex * This method is lenient to {@code null} values for {@code executor} and {@code snapshot}:
    * If {@code executor == null} the common {@link java.util.concurrent.ForkJoinPool ForkJoinPool} is used as * specified by {@link CompletableFuture#supplyAsync(Supplier)}.
    - * If {@code snapshot == null} a {@link ContextManagers#createContextSnapshot() new context snapshot} is - * created for the {@link Supplier} (if not already a {@link SupplierWithContext}). + * If {@code snapshot == null} a {@link ContextSnapshot#capture() new context snapshot} is + * captured for the {@link Supplier} (if not already a {@link SupplierWithContext}). * * @param runnable the action to run before completing the returned CompletableFuture * @param executor the executor to use for asynchronous execution diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorService.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorService.java index 24b57541..53a8a62a 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorService.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorService.java @@ -17,7 +17,6 @@ import nl.talsmasoftware.context.api.ContextSnapshot; import nl.talsmasoftware.context.api.ContextSnapshot.Reactivation; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.core.delegation.DelegatingExecutorService; import java.util.concurrent.Callable; @@ -47,7 +46,7 @@ public ContextAwareExecutorService(ExecutorService delegate) { @Override protected Callable wrap(final Callable callable) { - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); return () -> { try (Reactivation reactivation = snapshot.reactivate()) { return callable.call(); @@ -57,7 +56,7 @@ protected Callable wrap(final Callable callable) { @Override protected Runnable wrap(final Runnable runnable) { - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); return () -> { try (Reactivation reactivation = snapshot.reactivate()) { runnable.run(); diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextSnapshotHolder.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextSnapshotHolder.java index 4547e459..a51011b4 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextSnapshotHolder.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/concurrent/ContextSnapshotHolder.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.concurrent; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Supplier; @@ -40,7 +39,7 @@ final class ContextSnapshotHolder implements Consumer, Supplier * Optional, if {@code null} the holder will initialize with a new snapshot. */ ContextSnapshotHolder(ContextSnapshot snapshot) { - this.snapshot = (snapshot == null ? ContextManagers.createContextSnapshot() : snapshot); + this.snapshot = (snapshot == null ? ContextSnapshot.capture() : snapshot); } /** diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/delegation/WrapperWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/delegation/WrapperWithContext.java index 682c035f..b31f48d8 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/delegation/WrapperWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/delegation/WrapperWithContext.java @@ -49,7 +49,7 @@ protected WrapperWithContext(final ContextSnapshot snapshot, final T delegate) { *

    * Note: Make sure the supplier function does not obtain the context snapshot * from any threadlocal storage! The wrapper is designed to propagate contexts from one thread to another. - * Therefore, the snapshot must be {@link nl.talsmasoftware.context.core.ContextManagers#createContextSnapshot() captured} + * Therefore, the snapshot must be {@link ContextSnapshot#capture() captured} * in the source thread and {@link ContextSnapshot#reactivate() reactivated} in the target thread. * If unsure, please use the * {@link #WrapperWithContext(ContextSnapshot, Object) constructor with snapshot} instead. diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiConsumerWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiConsumerWithContext.java index da28e1de..7069294a 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiConsumerWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiConsumerWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -64,7 +63,7 @@ public BiConsumerWithContext(ContextSnapshot snapshot, BiConsumer delegate *

  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • accept the values by passing them to the delegate bi-consumer *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -103,7 +102,7 @@ protected BiConsumerWithContext(Supplier snapshotSupplier, BiCo *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • accept the values by passing them to the delegate bi-consumer *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -118,7 +117,7 @@ public void accept(T in1, U in2) { delegate().accept(in1, in2); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -141,7 +140,7 @@ public void accept(T in1, U in2) { *
  • passing them to the {@code after} bi-consumer * *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -159,7 +158,7 @@ public BiConsumer andThen(BiConsumer after) { after.accept(l, r); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiFunctionWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiFunctionWithContext.java index aef51c86..0953d729 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiFunctionWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiFunctionWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -73,7 +72,7 @@ public BiFunctionWithContext(ContextSnapshot snapshot, BiFunction *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate function *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result from the delegate function call (or throw runtime exception if the delegate did). * @@ -113,7 +112,7 @@ protected BiFunctionWithContext(Supplier snapshotSupplier, BiFu *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate bi-function and get the result *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result
  • * @@ -131,7 +130,7 @@ public OUT apply(IN1 in1, IN2 in2) { return delegate().apply(in1, in2); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -150,7 +149,7 @@ public OUT apply(IN1 in1, IN2 in2) { *
  • apply the delegate bi-function and get the result *
  • apply the {@code after} function to the result to get the end result *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the end result
  • * @@ -169,7 +168,7 @@ public BiFunction andThen(Function af return after.apply(delegate().apply(in1, in2)); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiPredicateWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiPredicateWithContext.java index a35e881f..49d6376e 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiPredicateWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BiPredicateWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.BiPredicate; import java.util.function.Consumer; @@ -71,7 +70,7 @@ public BiPredicateWithContext(ContextSnapshot snapshot, BiPredicate de *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • test the delegate bi-predicate and get the outcome *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return bi-predicate outcome (or throw runtime exception if the delegate did). * @@ -111,7 +110,7 @@ protected BiPredicateWithContext(Supplier snapshotSupplier, BiP *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • test the bi-delegate predicate and get the outcome *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the outcome
  • * @@ -128,7 +127,7 @@ public boolean test(IN1 in1, IN2 in2) { return delegate().test(in1, in2); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -149,7 +148,7 @@ public boolean test(IN1 in1, IN2 in2) { *
  • test the delegate bi-predicate and get the outcome *
  • if the outcome is true, test the {@code other} bi-predicate and return that outcome
  • *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the final outcome
  • * @@ -173,7 +172,7 @@ public BiPredicate and(BiPredicate other) { return delegate().test(in1, in2) && other.test(in1, in2); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -195,7 +194,7 @@ public BiPredicate and(BiPredicate other) { *
  • test the delegate bi-predicate and get the outcome *
  • if the outcome is false, test the {@code other} vi-predicate and return that outcome
  • *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the final outcome
  • * @@ -218,7 +217,7 @@ public BiPredicate or(BiPredicate other) { return delegate().test(in1, in2) || other.test(in1, in2); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BinaryOperatorWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BinaryOperatorWithContext.java index 36d74579..32b99197 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BinaryOperatorWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BinaryOperatorWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.BinaryOperator; import java.util.function.Consumer; @@ -64,7 +63,7 @@ public BinaryOperatorWithContext(ContextSnapshot snapshot, BinaryOperator del *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate binary operator *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result from the delegate operator call (or throw runtime exception if the delegate did). * diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContext.java index 85b9e9db..bd8dfa04 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -67,7 +66,7 @@ public BooleanSupplierWithContext(ContextSnapshot snapshot, BooleanSupplier dele *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • getting the outcome from the delegate boolean supplier *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the outcome from the delegate boolean supplier call (or throw runtime exception if the delegate did). * @@ -107,7 +106,7 @@ protected BooleanSupplierWithContext(Supplier snapshotSupplier, *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • get the outcome from the delegate boolean supplier *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the outcome
  • * @@ -120,7 +119,7 @@ public boolean getAsBoolean() { return delegate().getAsBoolean(); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/ConsumerWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/ConsumerWithContext.java index 2c7811e5..9b42909a 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/ConsumerWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/ConsumerWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Supplier; @@ -62,7 +61,7 @@ public ConsumerWithContext(ContextSnapshot snapshot, Consumer delegate) { *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • accept the value by passing it to the delegate consumer *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -101,7 +100,7 @@ protected ConsumerWithContext(Supplier snapshotSupplier, Consum *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • accept the value by passing it to the delegate consumer *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -115,7 +114,7 @@ public void accept(T value) { delegate().accept(value); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -138,7 +137,7 @@ public void accept(T value) { *
  • passing it to the {@code after} consumer * *
  • if snapshot consumer is non-null, - * pass it a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} + * pass it a {@linkplain ContextSnapshot#capture() new context snapshot} *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -156,7 +155,7 @@ public Consumer andThen(Consumer after) { after.accept(t); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/FunctionWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/FunctionWithContext.java index 60281484..65999143 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/FunctionWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/FunctionWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Function; @@ -71,7 +70,7 @@ public FunctionWithContext(ContextSnapshot snapshot, Function delegate) *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate function *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result from the delegate function call (or throw runtime exception if the delegate did). * @@ -111,7 +110,7 @@ protected FunctionWithContext(Supplier snapshotSupplier, Functi *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate function and get the result *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result
  • * @@ -127,7 +126,7 @@ public OUT apply(IN in) { return delegate().apply(in); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -146,7 +145,7 @@ public OUT apply(IN in) { *
  • apply the {@code before} function *
  • apply the delegate function to the result of the {@code before} function and get the end result *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the end result
  • * @@ -164,7 +163,7 @@ public Function compose(Function before) { return delegate().apply(before.apply(v)); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -184,7 +183,7 @@ public Function compose(Function before) { *
  • apply the delegate function and get the result *
  • apply the {@code after} function to the result to get the end result *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the end result
  • * @@ -202,7 +201,7 @@ public Function andThen(Function after) { return after.apply(delegate().apply(in)); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/PredicateWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/PredicateWithContext.java index 16563168..021a1956 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/PredicateWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/PredicateWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Predicate; @@ -70,7 +69,7 @@ public PredicateWithContext(ContextSnapshot snapshot, Predicate delegate) { *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • test the delegate predicate and get the outcome *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return predicate outcome (or throw runtime exception if the delegate did). * @@ -110,7 +109,7 @@ protected PredicateWithContext(Supplier snapshotSupplier, Predi *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • test the delegate predicate and get the outcome *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the outcome
  • * @@ -126,7 +125,7 @@ public boolean test(T value) { return delegate().test(value); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -147,7 +146,7 @@ public boolean test(T value) { *
  • test the delegate predicate and get the outcome *
  • if the outcome is true, test the {@code other} predicate and return that outcome
  • *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the final outcome
  • * @@ -171,7 +170,7 @@ public Predicate and(Predicate other) { return delegate().test(t) && other.test(t); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } @@ -193,7 +192,7 @@ public Predicate and(Predicate other) { *
  • test the delegate predicate and get the outcome *
  • if the outcome is false, test the {@code other} predicate and return that outcome
  • *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the final outcome
  • * @@ -216,7 +215,7 @@ public Predicate or(Predicate other) { return delegate().test(t) || other.test(t); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/RunnableWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/RunnableWithContext.java index da0251db..81d1c655 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/RunnableWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/RunnableWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Supplier; @@ -58,7 +57,7 @@ public RunnableWithContext(ContextSnapshot snapshot, Runnable delegate) { *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • run the delegate task *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -97,7 +96,7 @@ protected RunnableWithContext(Supplier snapshotSupplier, Runnab *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • run the delegate task *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * */ @@ -109,7 +108,7 @@ public void run() { delegate().run(); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.finest(() -> "Captured context snapshot after delegation: " + resultSnapshot + "."); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/SupplierWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/SupplierWithContext.java index b1b85327..bf8d9425 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/SupplierWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/SupplierWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Supplier; @@ -60,7 +59,7 @@ public SupplierWithContext(ContextSnapshot snapshot, Supplier delegate) { *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • supply the value by calling the delegate *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} * * @@ -99,7 +98,7 @@ protected SupplierWithContext(Supplier snapshotSupplier, Suppli *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • get the result from the delegate supplier *
  • if context snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result
  • * @@ -112,7 +111,7 @@ public T get() { return delegate().get(); } finally { if (contextSnapshotConsumer != null) { - ContextSnapshot resultSnapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot resultSnapshot = ContextSnapshot.capture(); LOGGER.log(Level.FINEST, "Captured context snapshot after delegation: {0}", resultSnapshot); contextSnapshotConsumer.accept(resultSnapshot); } diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/UnaryOperatorWithContext.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/UnaryOperatorWithContext.java index caca8c8e..e5c5ee57 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/UnaryOperatorWithContext.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/function/UnaryOperatorWithContext.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import java.util.function.Consumer; import java.util.function.Supplier; @@ -64,7 +63,7 @@ public UnaryOperatorWithContext(ContextSnapshot snapshot, UnaryOperator deleg *
  • {@linkplain ContextSnapshot#reactivate() reactivate} the given snapshot *
  • apply the delegate operator *
  • if snapshot consumer is non-null, - * pass a {@linkplain ContextManagers#createContextSnapshot() new context snapshot} to the consumer + * pass a {@linkplain ContextSnapshot#capture() new context snapshot} to the consumer *
  • close the {@linkplain ContextSnapshot.Reactivation reactivation} *
  • return the result from the delegate operator call (or throw runtime exception if the delegate did). * diff --git a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/package-info.java b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/package-info.java index 15bb8b57..3bd84199 100644 --- a/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/package-info.java +++ b/context-propagation-core/src/main/java/nl/talsmasoftware/context/core/package-info.java @@ -69,18 +69,6 @@ *
* * - *

{@linkplain nl.talsmasoftware.context.core.ContextManagers ContextManagers}

- *

- * Utility class to interact with all detected {@linkplain nl.talsmasoftware.context.api.ContextManager ContextManager} - * implementations at once, combining all - * their {@linkplain nl.talsmasoftware.context.api.ContextManager#getActiveContextValue() active context values} - * into a single {@linkplain nl.talsmasoftware.context.api.ContextSnapshot context snapshot} that can be reactivated - * in another thread. - *

- * Although this utility class is public and it is allowed to interact with it, - * it is advised to use one of the ContextAware.. or ..WithContext classes instead.
- * They make it much easier to close the reactivated snapshot again in a proper manner. - * * @author Sjoerd Talsma */ package nl.talsmasoftware.context.core; diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/clearable/ClearableContextManagerTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/clearable/ClearableContextManagerTest.java index 5f335690..5a56fdc1 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/clearable/ClearableContextManagerTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/clearable/ClearableContextManagerTest.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.clearable; import nl.talsmasoftware.context.api.ContextManager; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.ThrowingContextManager; import org.junit.jupiter.api.Test; @@ -42,7 +41,7 @@ public void testClearActiveContexts_byManager() { CLEARABLE.initializeNewContext("Third value"); assertThat(CLEARABLE.getActiveContextValue(), is("Third value")); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(CLEARABLE.getActiveContextValue(), is(nullValue())); } @@ -50,7 +49,7 @@ public void testClearActiveContexts_byManager() { public void testClearActiveContexts_exception() { ThrowingContextManager.onGet = new IllegalStateException("Cannot get the current active context!"); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); // Mustn't throw exceptions. } } diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextSnapshotTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextSnapshotTest.java index 002948aa..99decb02 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextSnapshotTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/ContextSnapshotTest.java @@ -33,13 +33,13 @@ public class ContextSnapshotTest { @Test public void testSnapshotToString() { - assertThat(ContextManagers.createContextSnapshot(), hasToString(startsWith("ContextSnapshot{size="))); + assertThat(ContextSnapshot.capture(), hasToString(startsWith("ContextSnapshot{size="))); } @Test public void testSnapshotReactivate() { try (Context ctx = MGR.initializeNewContext("Old value")) { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); try (Context ctx2 = MGR.initializeNewContext("New value")) { assertThat(MGR.getActiveContextValue(), is("New value")); diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/NoContextManagersTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/NoContextManagersTest.java index c7ede91b..399b591f 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/NoContextManagersTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/NoContextManagersTest.java @@ -36,21 +36,21 @@ public class NoContextManagersTest { @BeforeEach public void avoidContextManagersCache() { - ContextManagers.useClassLoader(new ClassLoader(Thread.currentThread().getContextClassLoader()) { + ContextManager.useClassLoader(new ClassLoader(Thread.currentThread().getContextClassLoader()) { }); assertThat("Move service file", SERVICE_FILE.renameTo(TMP_SERVICE_FILE), is(true)); } @AfterEach public void resetDefaultClassLoader() { - ContextManagers.useClassLoader(null); + ContextManager.useClassLoader(null); assertThat("Restore service file!", TMP_SERVICE_FILE.renameTo(SERVICE_FILE), is(true)); } @Test public void testReactivate_withoutContextManagers() { Context ctx1 = new DummyContext("foo"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); ctx1.close(); ContextSnapshot.Reactivation reactivated = snapshot.reactivate(); @@ -59,7 +59,7 @@ public void testReactivate_withoutContextManagers() { @Test public void testCreateSnapshot_withoutContextManagers() { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat(snapshot, is(notNullValue())); ContextSnapshot.Reactivation reactivated = snapshot.reactivate(); @@ -69,7 +69,7 @@ public void testCreateSnapshot_withoutContextManagers() { @Test public void testClearManagedContexts_withoutContextManagers() { - ContextManagers.clearActiveContexts(); // there should be no exception + ContextManager.clearAll(); // there should be no exception } } diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/TimersTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/TimersTest.java deleted file mode 100644 index a5c23ab6..00000000 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/TimersTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016-2024 Talsma ICT - * - * 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 - * - * 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 nl.talsmasoftware.context.core; - -import nl.talsmasoftware.context.api.ContextTimer; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -/** - * Test for the package-protected Timers utility class. - * - * @author Sjoerd Talsma - */ -public class TimersTest { - - @Test - public void testTimingDelegation() { - Timers.timed(TimeUnit.MILLISECONDS.toNanos(150), getClass(), "testTimingDelegation", null); - assertThat(TestContextTimer.getLastTimedMillis(getClass(), "testTimingDelegation"), is(150L)); - } - - public static class TestContextTimer implements ContextTimer { - private static final Map LAST_TIMED = new HashMap(); - - public static Long getLastTimedMillis(Class type, String method) { - return LAST_TIMED.get(type.getName() + "." + method); - } - - public void update(Class type, String method, long duration, TimeUnit unit, Throwable error) { - LAST_TIMED.put(type.getName() + "." + method, unit.toMillis(duration)); - } - - } -} diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/CompletedFutureTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/CompletedFutureTest.java index bfc7d660..53732c0f 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/CompletedFutureTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/CompletedFutureTest.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.concurrent; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -56,7 +55,7 @@ public void testCompletedFutureTakesNewSnapshot() throws ExecutionException, Int @Test public void testCompletedFutureAppliesGivenSnapshot() throws ExecutionException, InterruptedException { manager.initializeNewContext("Mr. Blonde"); - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); manager.initializeNewContext("Mr. Brown"); final CompletableFuture completed = ContextAwareCompletableFuture.completedFuture("Mr. Blue", snapshot); manager.initializeNewContext("Mr. Orange"); diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFutureTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFutureTest.java index c2322a88..a1dadc47 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFutureTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareCompletableFutureTest.java @@ -17,7 +17,6 @@ import nl.talsmasoftware.context.api.Context; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContext; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.junit.jupiter.api.AfterEach; @@ -112,7 +111,7 @@ public void testSupplyAsync_executor() throws ExecutionException, InterruptedExc @Test public void testSupplyAsync_executor_snapshot() throws ExecutionException, InterruptedException { try (Context ctx = manager.initializeNewContext("Vincent Vega")) { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Jules Winnfield"); assertContext("Jules Winnfield"); @@ -124,7 +123,7 @@ public void testSupplyAsync_executor_snapshot() throws ExecutionException, Inter @Test public void testSupplyAsync_executor_snapshot_takeNewSnapshot() throws ExecutionException, InterruptedException { try (Context ctx = manager.initializeNewContext("Vincent Vega")) { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Jules Winnfield"); assertContext("Jules Winnfield"); @@ -160,7 +159,7 @@ public void testRunAsync_executor() throws ExecutionException, InterruptedExcept @Test public void testRunAsync_executor_snapshot() throws ExecutionException, InterruptedException { try (Context ctx = manager.initializeNewContext("Pumpkin")) { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Honey Bunny"); assertContext("Honey Bunny"); @@ -172,7 +171,7 @@ public void testRunAsync_executor_snapshot() throws ExecutionException, Interrup @Test public void testRunAsync_executor_snapshot_takeNewSnapshot() throws ExecutionException, InterruptedException { try (Context ctx = manager.initializeNewContext("Pumpkin")) { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Honey Bunny"); assertContext("Honey Bunny"); @@ -1407,7 +1406,7 @@ public void testAllOf() throws ExecutionException, InterruptedException { @Test public void testAllOfWithSpecificSnapshot() throws ExecutionException, InterruptedException { DummyContext.setCurrentValue("Vincent Vega"); - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Marcellus Wallace"); CompletableFuture cf1 = new CompletableFuture<>(); CompletableFuture cf2 = new ContextAwareCompletableFuture().takeNewSnapshot().thenApply(s -> { @@ -1446,7 +1445,7 @@ public void testAnyOf() throws ExecutionException, InterruptedException { @Test public void testAnyOfWithSpecificSnapshot() throws ExecutionException, InterruptedException { DummyContext.setCurrentValue("Vincent Vega"); - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); DummyContext.setCurrentValue("Marcellus Wallace"); CompletableFuture cf1 = new CompletableFuture<>(); CompletableFuture cf2 = new ContextAwareCompletableFuture().takeNewSnapshot().thenApply(s -> { diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorServiceTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorServiceTest.java index cf15f253..1042fe6f 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorServiceTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/ContextAwareExecutorServiceTest.java @@ -15,7 +15,7 @@ */ package nl.talsmasoftware.context.core.concurrent; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.dummy.DummyContextManager; import nl.talsmasoftware.context.dummy.ThrowingContextManager; import org.junit.jupiter.api.AfterEach; @@ -58,7 +58,7 @@ public void tearDownExecutor() throws InterruptedException { @BeforeEach @AfterEach public void clearActiveContexts() { - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); } @Test diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/FailedFutureTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/FailedFutureTest.java index ebc334d9..96446c4f 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/FailedFutureTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/concurrent/FailedFutureTest.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.concurrent; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -57,7 +56,7 @@ public void testFailedFutureTakesNewSnapshot() throws ExecutionException, Interr @Test public void testFailedFutureAppliesGivenSnapshot() throws ExecutionException, InterruptedException { manager.initializeNewContext("Mr. Blonde"); - final ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + final ContextSnapshot snapshot = ContextSnapshot.capture(); manager.initializeNewContext("Mr. Brown"); final CompletableFuture completed = ContextAwareCompletableFuture.failedFuture(new NullPointerException("Mr. Blue"), snapshot); manager.initializeNewContext("Mr. Orange"); diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BiConsumerWithContextTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BiConsumerWithContextTest.java index 39700b13..4cae5f36 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BiConsumerWithContextTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BiConsumerWithContextTest.java @@ -18,7 +18,6 @@ import nl.talsmasoftware.context.api.Context; import nl.talsmasoftware.context.api.ContextSnapshot; import nl.talsmasoftware.context.api.ContextSnapshot.Reactivation; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -88,7 +87,7 @@ public void testAcceptWithSnapshotConsumer() throws InterruptedException { final ContextSnapshot[] snapshotHolder = new ContextSnapshot[1]; BiConsumer consumer = new BiConsumerWithContext<>( - ContextManagers.createContextSnapshot(), + ContextSnapshot.capture(), (a, b) -> { assertThat("Context must propagate into thread", currentValue(), is(Optional.of("Old value"))); String newValue = format("%s %s", a, b); @@ -121,7 +120,7 @@ public void testAndThen() throws InterruptedException { setCurrentValue("Old value"); BiConsumer consumer1 = new BiConsumerWithContext<>( - ContextManagers.createContextSnapshot(), + ContextSnapshot.capture(), (a, b) -> setCurrentValue(a + " " + b + ", " + Optional.ofNullable(currentValue()).orElse("NO VALUE")), s -> snapshotHolder[0] = s); BiConsumer consumer2 = consumer1.andThen( diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContextTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContextTest.java index b6310428..8889f0c6 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContextTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/BooleanSupplierWithContextTest.java @@ -16,7 +16,6 @@ package nl.talsmasoftware.context.core.function; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContext; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.junit.jupiter.api.AfterEach; @@ -87,7 +86,7 @@ public void testGetAsBooleanWithSnapshotConsumer() throws ExecutionException, In DummyContext.setCurrentValue("true"); final ContextSnapshot[] snapshotHolder = new ContextSnapshot[1]; - BooleanSupplier supplier = new BooleanSupplierWithContext(ContextManagers.createContextSnapshot(), () -> { + BooleanSupplier supplier = new BooleanSupplierWithContext(ContextSnapshot.capture(), () -> { try { return Boolean.parseBoolean(DummyContext.currentValue()); } finally { diff --git a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/ConsumerWithContextTest.java b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/ConsumerWithContextTest.java index fac9a614..927bc32b 100644 --- a/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/ConsumerWithContextTest.java +++ b/context-propagation-core/src/test/java/nl/talsmasoftware/context/core/function/ConsumerWithContextTest.java @@ -17,7 +17,6 @@ import nl.talsmasoftware.context.api.Context; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.dummy.DummyContextManager; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; @@ -83,7 +82,7 @@ public void testAcceptWithSnapshotConsumer() throws InterruptedException { final ContextSnapshot[] snapshotHolder = new ContextSnapshot[1]; ConsumerWithContext consumer = new ConsumerWithContext<>( - ContextManagers.createContextSnapshot(), + ContextSnapshot.capture(), val -> { assertThat("Context must propagate into thread", currentValue(), is(Optional.of("Old value"))); setCurrentValue(val); @@ -115,7 +114,7 @@ public void testAndThen() throws InterruptedException { final ContextSnapshot[] snapshotHolder = new ContextSnapshot[1]; Consumer consumer = new ConsumerWithContext( - ContextManagers.createContextSnapshot(), + ContextSnapshot.capture(), val -> setCurrentValue(val + ", " + Optional.ofNullable(currentValue()).orElse("NO VALUE")), s -> snapshotHolder[0] = s) .andThen(val -> setCurrentValue(val.toUpperCase() + ", " + Optional.ofNullable(currentValue()).orElse("NO VALUE"))); diff --git a/context-propagation-core/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer b/context-propagation-core/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer deleted file mode 100644 index da50995f..00000000 --- a/context-propagation-core/src/test/resources/META-INF/services/nl.talsmasoftware.context.api.ContextTimer +++ /dev/null @@ -1 +0,0 @@ -nl.talsmasoftware.context.core.TimersTest$TestContextTimer diff --git a/managers/context-manager-locale/src/test/java/nl/talsmasoftware/context/managers/locale/CurrentLocaleManagerTest.java b/managers/context-manager-locale/src/test/java/nl/talsmasoftware/context/managers/locale/CurrentLocaleManagerTest.java index 1c4fa945..d1a857c8 100644 --- a/managers/context-manager-locale/src/test/java/nl/talsmasoftware/context/managers/locale/CurrentLocaleManagerTest.java +++ b/managers/context-manager-locale/src/test/java/nl/talsmasoftware/context/managers/locale/CurrentLocaleManagerTest.java @@ -16,7 +16,7 @@ package nl.talsmasoftware.context.managers.locale; import nl.talsmasoftware.context.api.Context; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -128,7 +128,7 @@ public void testClearActiveContexts() { Context dutchCtx = MANAGER.initializeNewContext(DUTCH); Context englishCtx = MANAGER.initializeNewContext(ENGLISH); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(MANAGER.getActiveContextValue(), is(nullValue())); assertThat(CurrentLocaleHolder.getOrDefault(), is(DEFAULT_LOCALE)); diff --git a/managers/context-manager-log4j2/README.md b/managers/context-manager-log4j2/README.md index 25c69b92..2c7a7648 100644 --- a/managers/context-manager-log4j2/README.md +++ b/managers/context-manager-log4j2/README.md @@ -21,7 +21,7 @@ Add it to your classpath. Done! Now the data of the Log4j 2 Thread Context is copied into each snapshot -from the `ContextManagers.createSnapshot()` method +from the `ContextSnapshot.capture()` method to be reactivated by the `Contextsnapshot.reactivate()` call. The `ContextAwareExecutorService` automatically propagates the full Thread Context data into all executed tasks this way. @@ -31,7 +31,7 @@ data, if any: Thread Context stack values are pushed on top of the existing stack; map entries are added to the existing map, only replacing existing ones in case of a map key conflict. -Calling `ContextManagers.clearActiveContexts()` will clear the Thread Context +Calling `ContextManager.clearAll()` will clear the Thread Context data of the current thread. [maven-img]: https://img.shields.io/maven-central/v/nl.talsmasoftware.context/log4j2-propagation diff --git a/managers/context-manager-log4j2/src/test/java/nl/talsmasoftware/context/managers/log4j2/threadcontext/Log4j2ThreadContextManagerTest.java b/managers/context-manager-log4j2/src/test/java/nl/talsmasoftware/context/managers/log4j2/threadcontext/Log4j2ThreadContextManagerTest.java index d5962b00..f13bc858 100644 --- a/managers/context-manager-log4j2/src/test/java/nl/talsmasoftware/context/managers/log4j2/threadcontext/Log4j2ThreadContextManagerTest.java +++ b/managers/context-manager-log4j2/src/test/java/nl/talsmasoftware/context/managers/log4j2/threadcontext/Log4j2ThreadContextManagerTest.java @@ -16,8 +16,8 @@ package nl.talsmasoftware.context.managers.log4j2.threadcontext; import nl.talsmasoftware.context.api.Context; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.apache.logging.log4j.ThreadContext; import org.junit.jupiter.api.AfterEach; @@ -176,7 +176,7 @@ void testSnapshotRestorationAfterClosingReactivatedSnapshot() { ThreadContext.put(mapKey1, "value1"); ThreadContext.push("stack1"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat("New snapshot shouldn't manipulate ThreadContext map", ThreadContext.get(mapKey1), equalTo("value1")); assertThat(ThreadContext.getContext().size(), is(1)); assertThat("New snapshot shouldn't manipulate ThreadContext stack", ThreadContext.peek(), equalTo("stack1")); @@ -235,7 +235,7 @@ void testClearActiveContexts() { ThreadContext.put("map1", "value1"); ThreadContext.push("stack1"); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(ThreadContext.isEmpty(), is(true)); assertThat(ThreadContext.getDepth(), is(0)); diff --git a/managers/context-manager-opentelemetry/src/main/java/nl/talsmasoftware/context/managers/opentelemetry/OpenTelemetryContextManager.java b/managers/context-manager-opentelemetry/src/main/java/nl/talsmasoftware/context/managers/opentelemetry/OpenTelemetryContextManager.java index 0ccacbf5..b8c6011e 100644 --- a/managers/context-manager-opentelemetry/src/main/java/nl/talsmasoftware/context/managers/opentelemetry/OpenTelemetryContextManager.java +++ b/managers/context-manager-opentelemetry/src/main/java/nl/talsmasoftware/context/managers/opentelemetry/OpenTelemetryContextManager.java @@ -35,7 +35,8 @@ * *

* There is no need to instantiate the context manager yourself. - * Including it on the classpath will allow the {@code ContextManagers} class to detect it automatically. + * Including it on the classpath will allow the API to automatically include it in + * {@linkplain nl.talsmasoftware.context.api.ContextSnapshot context snapshots}. */ public class OpenTelemetryContextManager implements ContextManager { private static final OpenTelemetryContextManager INSTANCE = new OpenTelemetryContextManager(); diff --git a/managers/context-manager-opentracing/README.md b/managers/context-manager-opentracing/README.md index 855e1419..3833a6ac 100644 --- a/managers/context-manager-opentracing/README.md +++ b/managers/context-manager-opentracing/README.md @@ -21,7 +21,7 @@ Add it to your classpath. Done! Now the `GlobalTracer.get().activeSpan()` is included in each -snapshot created by the `ContextManagers.createSnapshot()` method +snapshot created by the `ContextSnapshot.capture()` method and reactivated with it. This includes all usages of the `ContextAwareExecutorService`. diff --git a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/ContextScopeManagerTest.java b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/ContextScopeManagerTest.java index 587d1ecb..a8edb360 100644 --- a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/ContextScopeManagerTest.java +++ b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/ContextScopeManagerTest.java @@ -21,7 +21,7 @@ import io.opentracing.util.GlobalTracer; import io.opentracing.util.GlobalTracerTestUtil; import nl.talsmasoftware.context.api.Context; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -59,7 +59,7 @@ public void registerMockGlobalTracer() { @AfterEach public void cleanup() { threadpool.shutdown(); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); GlobalTracerTestUtil.resetGlobalTracer(); } diff --git a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/Issue30Test.java b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/Issue30Test.java index 982ef344..711bcb03 100644 --- a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/Issue30Test.java +++ b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/Issue30Test.java @@ -21,7 +21,6 @@ import io.opentracing.util.GlobalTracerTestUtil; import io.opentracing.util.ThreadLocalScopeManager; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,12 +36,14 @@ *

* span can be {@code null} in {@code ScopeContext} if {@code OpentracingSpanManager} is used with * ContextAware* when there is no active span.
- * The problem is that {@code ContextManagers.createContextSnapshot()} only stores + * The problem is that {@code ContextSnapshot.capture()} only stores * {@code activeContext.getValue()} which is {@code null}
- * {@code ContextManagers.reactivate()} then retreives {@code null} from the snapshot and + * {@code ContextSnapshot.reactivate()} then retreives {@code null} from the snapshot and * calls {@code OpentracingSpanManger.initializeNewContext(null)} + * *

* The test in ScopeContext.close only checks that closed is false before calling span.close. + * *

* The fix could be to set closed to true in initializeNewContext() if span is null, * or add a nullcheck in SpanContext.close. @@ -69,7 +70,7 @@ public void cleanup() { @Test public void testIssue30NullPointerException() { - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); ContextSnapshot.Reactivation reactivation = snapshot.reactivate(); reactivation.close(); // This throws NPE in issue 30 } diff --git a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/SpanManagerTest.java b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/SpanManagerTest.java index e64ea9ee..8ce1e297 100644 --- a/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/SpanManagerTest.java +++ b/managers/context-manager-opentracing/src/test/java/nl/talsmasoftware/context/managers/opentracing/SpanManagerTest.java @@ -23,7 +23,7 @@ import io.opentracing.util.GlobalTracer; import io.opentracing.util.GlobalTracerTestUtil; import io.opentracing.util.ThreadLocalScopeManager; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -212,7 +212,7 @@ public void testClearingAllContexts() { Scope scope = mockTracer.scopeManager().activate(span); assertThat(SpanManager.provider().getActiveContextValue(), is(sameInstance(span))); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); // TODO Test after this is merged: https://github.com/opentracing/opentracing-java/pull/313 // assertThat(SpanManager.provider().getActiveContextValue(), is(nullValue())); } diff --git a/managers/context-manager-servletrequest/README.md b/managers/context-manager-servletrequest/README.md index e0efdc4c..e19899cf 100644 --- a/managers/context-manager-servletrequest/README.md +++ b/managers/context-manager-servletrequest/README.md @@ -1,4 +1,4 @@ -[![Maven Version][maven-img]][maven] +[![Maven Version][maven-img]][maven] # ServletRequest propagation library @@ -23,9 +23,10 @@ if the `ServletRequestContextFilter` was applied to the inbound request. Done! Now the `ServletRequestContextManager.currentServletRequest()` is propagated into each -snapshot created by the `ContextManagers.createSnapshot()` method. +snapshot created by the `ContextSnapshot.capture()` method. This includes all usages of the `ContextAwareExecutorService`. - [maven-img]: https://img.shields.io/maven-central/v/nl.talsmasoftware.context/servletrequest-propagation - [maven]: https://search.maven.org/artifact/nl.talsmasoftware.context/servletrequest-propagation +[maven-img]: https://img.shields.io/maven-central/v/nl.talsmasoftware.context/servletrequest-propagation + +[maven]: https://search.maven.org/artifact/nl.talsmasoftware.context/servletrequest-propagation diff --git a/managers/context-manager-servletrequest/src/test/java/nl/talsmasoftware/context/managers/servletrequest/ServletRequestContextManagerTest.java b/managers/context-manager-servletrequest/src/test/java/nl/talsmasoftware/context/managers/servletrequest/ServletRequestContextManagerTest.java index 8d0bdfd7..b20c3759 100644 --- a/managers/context-manager-servletrequest/src/test/java/nl/talsmasoftware/context/managers/servletrequest/ServletRequestContextManagerTest.java +++ b/managers/context-manager-servletrequest/src/test/java/nl/talsmasoftware/context/managers/servletrequest/ServletRequestContextManagerTest.java @@ -16,7 +16,7 @@ package nl.talsmasoftware.context.managers.servletrequest; import nl.talsmasoftware.context.api.Context; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -91,7 +91,7 @@ public void testClearableImplementation() { assertThat(ctx.getValue(), is(sameInstance(request))); assertThat(ServletRequestContextManager.provider().getActiveContextValue(), is(sameInstance(request))); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(ctx.getValue(), is(nullValue())); // must have been closed assertThat(ServletRequestContextManager.provider().getActiveContextValue(), is(nullValue())); } diff --git a/managers/context-manager-slf4j/README.md b/managers/context-manager-slf4j/README.md index a78c6a11..aa3c2d5e 100644 --- a/managers/context-manager-slf4j/README.md +++ b/managers/context-manager-slf4j/README.md @@ -21,7 +21,7 @@ Add it to your classpath. Done! Now the `MDC.getCopyOfContextMap()` is copied into each snapshot -from the `ContextManagers.createSnapshot()` method +from the `ContextSnapshot.capture()` method to be reactivated by the `Contextsnapshot.reactivate()` call. The `ContextAwareExecutorService` automatically propagates the full [MDC] content into all executed tasks this way. diff --git a/managers/context-manager-slf4j/src/main/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManager.java b/managers/context-manager-slf4j/src/main/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManager.java index b69d1ed1..9bcd1e73 100644 --- a/managers/context-manager-slf4j/src/main/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManager.java +++ b/managers/context-manager-slf4j/src/main/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManager.java @@ -38,7 +38,7 @@ * *

* This manager does not implement the optional {@link #clear()} method. - * {@code ContextManagers.clearActiveContexts()} will therefore not clear the {@linkplain MDC}. + * {@linkplain ContextManager#clearAll()} will therefore not clear the {@linkplain MDC}. * Please use {@linkplain MDC#clear()} explicitly to do that. * * @author Sjoerd Talsma @@ -103,7 +103,7 @@ public Map getActiveContextValue() { * This manager does not support clearing the MDC. * *

- * Calling {@code ContextManagers.clearActiveContexts()} will therefore not clear the + * Calling {@linkplain ContextManager#clearAll()} will therefore not clear the * MDC by default. This can be achieved by calling {@link MDC#clear()} explicitly. * * @see MDC#clear() diff --git a/managers/context-manager-slf4j/src/test/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManagerTest.java b/managers/context-manager-slf4j/src/test/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManagerTest.java index 55481537..3b1056c1 100644 --- a/managers/context-manager-slf4j/src/test/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManagerTest.java +++ b/managers/context-manager-slf4j/src/test/java/nl/talsmasoftware/context/managers/slf4j/mdc/Slf4jMdcManagerTest.java @@ -16,8 +16,8 @@ package nl.talsmasoftware.context.managers.slf4j.mdc; import nl.talsmasoftware.context.api.Context; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -79,7 +79,7 @@ public void testMdcItemPropagation() throws ExecutionException, InterruptedExcep public void testMdcItemRestoration() throws Exception { MDC.put("mdc-item", "Value 1"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat("New snapshot shouldn't manipulate MDC.", GET_MDC_ITEM.call(), is("Value 1")); MDC.put("mdc-item", "Value 2"); @@ -113,7 +113,7 @@ public void testSlf4jMdcContextToString() { public void testClearActiveContexts() { MDC.put("dummy", "value"); // Test no-op for MdcManager - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(MDC.get("dummy"), is("value")); } } diff --git a/managers/context-manager-spring-security/README.md b/managers/context-manager-spring-security/README.md index 587653df..876a254c 100644 --- a/managers/context-manager-spring-security/README.md +++ b/managers/context-manager-spring-security/README.md @@ -22,7 +22,7 @@ Add it to your classpath. Done! Now the `SecurityContextHolder.getContext()` is copied into each snapshot -from the `ContextManagers.createSnapshot()` method +from the `ContextSnapshot.capture()` method to be reactivated by the `Contextsnapshot.reactivate()` call. The `ContextAwareExecutorService` automatically propagates the active [spring security] `Authentication` into all executed tasks this way. diff --git a/managers/context-manager-spring-security/src/test/java/nl/talsmasoftware/context/managers/spring/security/SpringSecurityContextManagerTest.java b/managers/context-manager-spring-security/src/test/java/nl/talsmasoftware/context/managers/spring/security/SpringSecurityContextManagerTest.java index 44e4ef4f..8ed175c5 100644 --- a/managers/context-manager-spring-security/src/test/java/nl/talsmasoftware/context/managers/spring/security/SpringSecurityContextManagerTest.java +++ b/managers/context-manager-spring-security/src/test/java/nl/talsmasoftware/context/managers/spring/security/SpringSecurityContextManagerTest.java @@ -15,8 +15,8 @@ */ package nl.talsmasoftware.context.managers.spring.security; +import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import nl.talsmasoftware.context.core.concurrent.ContextAwareExecutorService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -95,7 +95,7 @@ public void testAuthenticationPropagation() throws ExecutionException, Interrupt public void testAuthenticationReactivation() throws Exception { setAuthentication("Vincent Vega"); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat("New snapshot shouldn't manipulate context.", GET_AUTHENTICATION.call(), hasToString(containsString("Vincent Vega"))); @@ -117,7 +117,7 @@ public void testClearableImplementation() { setAuthentication("Vincent Vega"); assertThat(SpringSecurityContextManager.provider().getActiveContextValue().getName(), is("Vincent Vega")); - ContextManagers.clearActiveContexts(); + ContextManager.clearAll(); assertThat(SpringSecurityContextManager.provider().getActiveContextValue(), is(nullValue())); } diff --git a/readme.md b/readme.md index a320eaaa..196a4add 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ to make sure they reactivate _and_ close snapshots in a safe way. Just before creating a new thread, capture a snapshot of all ThreadLocal context values: ```java -ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); +ContextSnapshot snapshot = ContextSnapshot.capture(); ``` In the code of your background thread, activate the snapshot to have all ThreadLocal @@ -131,7 +131,7 @@ context snapshots along with time spent in each individual `ContextManager`. ### Logging performance On a development machine, you can get timing for each snapshot by turning on logging -for `nl.talsmasoftware.context.core.Timers` at `FINEST` or `TRACE` level +for `nl.talsmasoftware.context.api.ContextTimer` at `FINEST` or `TRACE` level (depending on your logger of choice). Please **do not** turn this on in production as the logging overhead will most likely have a noticeable impact on your application. diff --git a/timers/context-timer-metrics/README.md b/timers/context-timer-metrics/README.md index 36a35434..a2ef28ac 100644 --- a/timers/context-timer-metrics/README.md +++ b/timers/context-timer-metrics/README.md @@ -3,7 +3,7 @@ # Metrics instrumentation for context-propagation This module provides [metrics] `Timer` instrumentation for: - - all context snapshots that are created with `ContextManagers.createContextSnapshot()` + - all context snapshots that are created with `ContextSnapshot.capture()` - all context snapshots that are reactivated with `ContextSnapshot.reactivate()` - for each specific `ContextManager`: - calls to `ContextManager.getActiveContext` and diff --git a/timers/context-timer-metrics/src/test/java/nl/talsmasoftware/context/timers/metrics/MetricsContextTimerTest.java b/timers/context-timer-metrics/src/test/java/nl/talsmasoftware/context/timers/metrics/MetricsContextTimerTest.java index 60b10fd2..d043e1a1 100644 --- a/timers/context-timer-metrics/src/test/java/nl/talsmasoftware/context/timers/metrics/MetricsContextTimerTest.java +++ b/timers/context-timer-metrics/src/test/java/nl/talsmasoftware/context/timers/metrics/MetricsContextTimerTest.java @@ -18,7 +18,6 @@ import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.SharedMetricRegistries; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -70,8 +69,8 @@ public void resetCachesAndRegistry() { @Test public void testCreateSnapshotInFreshApplication() { assertThat(SharedMetricRegistries.names(), is(empty())); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); - String name = MetricRegistry.name(ContextManagers.class, "createContextSnapshot"); + ContextSnapshot snapshot = ContextSnapshot.capture(); + String name = MetricRegistry.name(ContextSnapshot.class, "capture"); assertThat(snapshot, is(notNullValue())); assertThat(SharedMetricRegistries.names(), contains("ContextPropagationMetrics")); @@ -85,8 +84,8 @@ public void testCreateSnapshotInApplicationWithDefaultRegistry() { SharedMetricRegistries.setDefault("DefaultRegistry"); assertThat(SharedMetricRegistries.names(), contains("DefaultRegistry")); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); - String name = MetricRegistry.name(ContextManagers.class, "createContextSnapshot"); + ContextSnapshot snapshot = ContextSnapshot.capture(); + String name = MetricRegistry.name(ContextSnapshot.class, "capture"); assertThat(snapshot, is(notNullValue())); assertThat(SharedMetricRegistries.names(), contains("DefaultRegistry")); // No new registries! @@ -101,8 +100,8 @@ public void testCreateSnapshotInApplicationWithSingleNonDefaultRegistry() { assertThat(SharedMetricRegistries.tryGetDefault(), is(nullValue())); assertThat(SharedMetricRegistries.names(), contains("NonDefaultRegistry")); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); - String name = MetricRegistry.name(ContextManagers.class, "createContextSnapshot"); + ContextSnapshot snapshot = ContextSnapshot.capture(); + String name = MetricRegistry.name(ContextSnapshot.class, "capture"); assertThat(snapshot, is(notNullValue())); assertThat(SharedMetricRegistries.names(), contains("NonDefaultRegistry")); // No new registries! @@ -118,9 +117,9 @@ public void testCreate3SnapshotsInApplicationWithMultipleNonDefaultRegistries() assertThat(SharedMetricRegistries.names(), containsInAnyOrder("NonDefaultRegistry1", "NonDefaultRegistry2")); for (int i = 1; i <= 3; i++) { - assertThat(ContextManagers.createContextSnapshot(), is(notNullValue())); + assertThat(ContextSnapshot.capture(), is(notNullValue())); } - String name = MetricRegistry.name(ContextManagers.class, "createContextSnapshot"); + String name = MetricRegistry.name(ContextSnapshot.class, "capture"); assertThat(registry1.getTimers().containsKey(name), is(true)); assertThat(registry1.timer(name).getCount(), is(3L)); diff --git a/timers/context-timer-micrometer/readme.md b/timers/context-timer-micrometer/readme.md index dfc00498..f9e04410 100644 --- a/timers/context-timer-micrometer/readme.md +++ b/timers/context-timer-micrometer/readme.md @@ -3,7 +3,7 @@ # Micrometer instrumentation for context-propagation This module provides [Micrometer] `Timer` instrumentation for: - - all context snapshots that are created with `ContextManagers.createContextSnapshot()` + - all context snapshots that are created with `ContextSnapshot.capture()` - all context snapshots that are reactivated with `ContextSnapshot.reactivate()` - for each specific `ContextManager`: - calls to `ContextManager.getActiveContext` and diff --git a/timers/context-timer-micrometer/src/test/java/nl/talsmasoftware/context/timers/micrometer/MicrometerContextTimerTest.java b/timers/context-timer-micrometer/src/test/java/nl/talsmasoftware/context/timers/micrometer/MicrometerContextTimerTest.java index 2a0b66dc..72d2812a 100644 --- a/timers/context-timer-micrometer/src/test/java/nl/talsmasoftware/context/timers/micrometer/MicrometerContextTimerTest.java +++ b/timers/context-timer-micrometer/src/test/java/nl/talsmasoftware/context/timers/micrometer/MicrometerContextTimerTest.java @@ -19,7 +19,6 @@ import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -49,10 +48,10 @@ public void shutdownRegistry() { @Test public void testCreateSnapshotInFreshApplication() { - Timer timer = Metrics.timer(ContextManagers.class.getName() + ".createContextSnapshot"); + Timer timer = Metrics.timer(ContextSnapshot.class.getName() + ".capture"); assertThat(timer.count(), is(0L)); - ContextSnapshot snapshot = ContextManagers.createContextSnapshot(); + ContextSnapshot snapshot = ContextSnapshot.capture(); assertThat(snapshot, is(notNullValue())); assertThat(timer.count(), is(1L)); diff --git a/timers/context-timer-opentelemetry/src/main/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimer.java b/timers/context-timer-opentelemetry/src/main/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimer.java index f2674e81..e760492e 100644 --- a/timers/context-timer-opentelemetry/src/main/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimer.java +++ b/timers/context-timer-opentelemetry/src/main/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimer.java @@ -93,7 +93,6 @@ private static String readVersion() { } private static boolean mustTrace(Class type) { - return ContextSnapshot.class.isAssignableFrom(type) - || "nl.talsmasoftware.context.core.ContextManagers".equals(type.getName()); + return ContextSnapshot.class.isAssignableFrom(type); } } diff --git a/timers/context-timer-opentelemetry/src/test/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimerTest.java b/timers/context-timer-opentelemetry/src/test/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimerTest.java index 2e13329d..118aec9f 100644 --- a/timers/context-timer-opentelemetry/src/test/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimerTest.java +++ b/timers/context-timer-opentelemetry/src/test/java/nl/talsmasoftware/context/timers/opentelemetry/OpenTelemetryContextTimerTest.java @@ -18,7 +18,6 @@ import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; import nl.talsmasoftware.context.api.ContextManager; import nl.talsmasoftware.context.api.ContextSnapshot; -import nl.talsmasoftware.context.core.ContextManagers; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -33,15 +32,15 @@ class OpenTelemetryContextTimerTest { OpenTelemetryContextTimer subject = new OpenTelemetryContextTimer(); @Test - void update_ContextManagers_createContextSnapshot() { + void update_ContextSnapshot_capture() { // prepare // execute - subject.update(ContextManagers.class, "createContextSnapshot", 5, TimeUnit.MILLISECONDS, null); + subject.update(ContextSnapshot.class, "capture", 5, TimeUnit.MILLISECONDS, null); // verify TELEMETRY.assertTraces().hasTracesSatisfyingExactly(trace -> - trace.hasSpansSatisfyingExactly(span -> span.hasName("ContextManagers.createContextSnapshot"))); + trace.hasSpansSatisfyingExactly(span -> span.hasName("ContextSnapshot.capture"))); } @Test diff --git a/timers/context-timer-opentracing/src/main/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimer.java b/timers/context-timer-opentracing/src/main/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimer.java index 3d382924..3f30a245 100644 --- a/timers/context-timer-opentracing/src/main/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimer.java +++ b/timers/context-timer-opentracing/src/main/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimer.java @@ -51,8 +51,8 @@ public void update(Class type, String method, long duration, TimeUnit unit, T Span span = GlobalTracer.get().buildSpan(operationName).withStartTimestamp(startTimestampMicros).start(); try { Map log = new LinkedHashMap<>(); - if ("createContextSnapshot".equals(method)) { - log.put(Fields.EVENT, "New context snapshot created"); + if ("capture".equals(method)) { + log.put(Fields.EVENT, "New context snapshot captured"); } else if ("reactivate".equals(method)) { log.put(Fields.EVENT, "Context snapshot reactivated"); } @@ -74,8 +74,7 @@ private static boolean reportContextSwitchesFor(Class type) { boolean enableTracing = false; // Only report spans for entire snapshots, not individual context managers. // Could be made configurable if somebody ever asks for it. - if (ContextSnapshot.class.isAssignableFrom(type) - || "nl.talsmasoftware.context.core.ContextManagers".equals(type.getName())) { + if (ContextSnapshot.class.isAssignableFrom(type)) { final String prop = System.getProperty(SYS_ENABLED, ENV_ENABLED); enableTracing = "1".equals(prop) || "true".equalsIgnoreCase(prop) || "enabled".equalsIgnoreCase(prop); } diff --git a/timers/context-timer-opentracing/src/test/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimerTest.java b/timers/context-timer-opentracing/src/test/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimerTest.java index d1d22b45..6acfe8ef 100644 --- a/timers/context-timer-opentracing/src/test/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimerTest.java +++ b/timers/context-timer-opentracing/src/test/java/nl/talsmasoftware/context/timers/opentracing/OpentracingContextTimerTest.java @@ -18,7 +18,7 @@ import io.opentracing.mock.MockTracer; import io.opentracing.util.GlobalTracer; import io.opentracing.util.GlobalTracerTestUtil; -import nl.talsmasoftware.context.core.ContextManagers; +import nl.talsmasoftware.context.api.ContextSnapshot; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -68,22 +68,22 @@ public void restoreSystemproperty() { @Test public void testDisabledByDefault() { - ContextManagers.createContextSnapshot().reactivate().close(); + ContextSnapshot.capture().reactivate().close(); assertThat(tracer.finishedSpans(), is(empty())); } @Test - public void testTraceCreateContextSnapshot() { + public void testTraceCaptureContextSnapshot() { System.setProperty(PROPERTY_NAME, "true"); - ContextManagers.createContextSnapshot(); - assertThat(tracer.finishedSpans(), hasItem(withOperationName("ContextManagers.createContextSnapshot"))); + ContextSnapshot.capture(); + assertThat(tracer.finishedSpans(), hasItem(withOperationName("ContextSnapshot.capture"))); } @Test public void testTraceReactivateContextSnapshot() { System.setProperty(PROPERTY_NAME, "true"); - ContextManagers.createContextSnapshot().reactivate().close(); + ContextSnapshot.capture().reactivate().close(); assertThat(tracer.finishedSpans(), hasItem(withOperationName("ContextSnapshot.reactivate"))); }