[ 
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

Reply via email to