[ https://issues.apache.org/jira/browse/LOG4J2-1517?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15421353#comment-15421353 ]
Ralph Goers commented on LOG4J2-1517: ------------------------------------- I'm fine with the "one at a time' method. If there was a way you could do this without making it valid for users I might be OK with it. But I have a fear that letting user's do this could cause all kinds of problems. > Add ThreadContext.setContext(Map<String, String>) > ------------------------------------------------- > > Key: LOG4J2-1517 > URL: https://issues.apache.org/jira/browse/LOG4J2-1517 > Project: Log4j 2 > Issue Type: New Feature > Reporter: Gary Gregory > Assignee: Gary Gregory > Fix For: 2.7 > > > Add {{Add ThreadContext.setContext(Map<String, String>)}}. > Note that we have {{ThreadContext.setStack(Collection<String>)}} to set the > whole stack but nothing to set the whole map. > My immediate goal is to be able to build a JUnit Rule to save and restore the > thread context around each unit test method and/or a given class. > I have (not committed yet): > {code:java} > /** > * Restores the ThreadContext to it's initial map and stack values after a > JUnit test. > */ > public class ThreadContextRule extends ExternalResource { > private final boolean restoreMap; > private final boolean restoreStack; > private ThreadContextHolder threadContextHolder; > /** > * Constructs an instance initialized to restore the stack and map. > */ > public ThreadContextRule() { > this(true, true); > } > /** > * Constructs an instance initialized to restore the given structures. > * > * @param restoreMap > * Whether to restore the thread context map. > * @param restoreStack > * Whether to restore the thread context stack. > */ > public ThreadContextRule(final boolean restoreMap, final boolean > restoreStack) { > super(); > this.restoreMap = restoreMap; > this.restoreStack = restoreStack; > } > @Override > protected void after() { > if (threadContextHolder != null) { > threadContextHolder.restore(); > } > } > @Override > protected void before() throws Throwable { > threadContextHolder = new ThreadContextHolder(restoreMap, > restoreStack); > if (restoreMap) { > ThreadContext.clearMap(); > } > if (restoreStack) { > ThreadContext.clearStack(); > } > } > } > {code} > and (in src/test): > {code:java} > /** > * Holds an immutable copy of the ThreadContext stack and map. > * > * TODO Use LOG4J2-1517 Add ThreadContext.setContext(Map<String, String>) > * > * or > * > * TODO Might be replaced by something from LOG4J2-1447. > * > * or do nothing. > * > * @since 2.7 > */ > public class ThreadContextHolder { > private final Map<String, String> immutableContext; > private final ContextStack immutableStack; > private final boolean restoreContext; > private final boolean restoreStack; > /** > * Constructs a new holder initialized with an immutable copy of the > ThreadContext stack and map. > * @param restoreContext > * @param restoreStack > */ > public ThreadContextHolder(final boolean restoreContext, final boolean > restoreStack) { > this.restoreContext = restoreContext; > this.restoreStack = restoreStack; > this.immutableContext = restoreContext ? > ThreadContext.getImmutableContext() : null; > this.immutableStack = restoreStack ? > ThreadContext.getImmutableStack() : null; > } > /** > * Restores the ThreadContext stack and map based on the values saved in > the constructor. > */ > public void restore() { > if (restoreStack) { > ThreadContext.setStack(immutableStack); > } > if (restoreContext) { > ThreadContext.setContext(immutableContext); > } > } > } > {code} > and in ThreadContext: > {code:java} > /** > * Sets this thread's context. > * > * @param map The map to use. > * @since 2.7 > */ > public static void setContext(final Map<String, String> map) { > if (map.isEmpty() || !useMap) { > return; > } > contextMap.clear(); > contextMap.putAll(map); > } > {code} > For convenience: > {code:java} > /** > * Restores the ThreadContext to it's initial map values after a JUnit test. > */ > public class ThreadContextMapRule extends ThreadContextRule { > /** > * Constructs an initialized instance. > */ > public ThreadContextMapRule() { > super(true, false); > } > } > /** > * Restores the ThreadContext to it's initial stack values after a JUnit test. > */ > public class ThreadContextStackRule extends ThreadContextRule { > /** > * Constructs an initialized instance. > */ > public ThreadContextStackRule() { > super(false, true); > } > } > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332) --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org