Class ThreadContext

java.lang.Object
org.elasticsearch.common.util.concurrent.ThreadContext
All Implemented Interfaces:
Writeable

public final class ThreadContext
extends java.lang.Object
implements Writeable
A ThreadContext is a map of string headers and a transient map of keyed objects that are associated with a thread. It allows to store and retrieve header information across method calls, network calls as well as threads spawned from a thread that has a ThreadContext associated with. Threads spawned from a ThreadPool have out of the box support for ThreadContext and all threads spawned will inherit the ThreadContext from the thread that it is forking from.". Network calls will also preserve the senders headers automatically.

Consumers of ThreadContext usually don't need to interact with adding or stashing contexts. Every elasticsearch thread is managed by a thread pool or executor being responsible for stashing and restoring the threads context. For instance if a network request is received, all headers are deserialized from the network and directly added as the headers of the threads ThreadContext (see readHeaders(StreamInput). In order to not modify the context that is currently active on this thread the network code uses a try/with pattern to stash it's current context, read headers into a fresh one and once the request is handled or a handler thread is forked (which in turn inherits the context) it restores the previous context. For instance:

     // current context is stashed and replaced with a default context
     try (StoredContext context = threadContext.stashContext()) {
         threadContext.readHeaders(in); // read headers into current context
         if (fork) {
             threadPool.execute(() -> request.handle()); // inherits context
         } else {
             request.handle();
         }
     }
     // previous context is restored on StoredContext#close()
 
  • Nested Class Summary

    Nested Classes 
    Modifier and Type Class Description
    static interface  ThreadContext.StoredContext  

    Nested classes/interfaces inherited from interface org.elasticsearch.common.io.stream.Writeable

    Writeable.Reader<V>, Writeable.Writer<V>
  • Field Summary

    Fields 
    Modifier and Type Field Description
    static java.lang.String ACTION_ORIGIN_TRANSIENT_NAME
    Name for the origin attribute.
    static Setting<Settings> DEFAULT_HEADERS_SETTING  
    static java.lang.String PREFIX  
  • Constructor Summary

    Constructors 
    Constructor Description
    ThreadContext​(Settings settings)
    Creates a new ThreadContext instance
  • Method Summary

    Modifier and Type Method Description
    void addResponseHeader​(java.lang.String key, java.lang.String value)
    Add the value for the specified key Any duplicate value is ignored.
    void addResponseHeader​(java.lang.String key, java.lang.String value, java.util.function.Function<java.lang.String,​java.lang.String> uniqueValue)
    Add the value for the specified key with the specified uniqueValue used for de-duplication.
    static java.util.Map<java.lang.String,​java.lang.String> buildDefaultHeaders​(Settings settings)  
    void copyHeaders​(java.lang.Iterable<java.util.Map.Entry<java.lang.String,​java.lang.String>> headers)
    Copies all header key, value pairs into the current context
    java.lang.String getHeader​(java.lang.String key)
    Returns the header for the given key or null if not present
    java.util.Map<java.lang.String,​java.lang.String> getHeaders()
    Returns all of the request contexts headers
    java.util.Map<java.lang.String,​java.util.List<java.lang.String>> getResponseHeaders()
    Get a copy of all response headers.
    <T> T getTransient​(java.lang.String key)
    Returns a transient header object or null if there is no header for the given key
    boolean isSystemContext()
    Returns true iff this context is a system context
    void markAsSystemContext()
    Marks this thread context as an internal system context.
    java.util.function.Supplier<ThreadContext.StoredContext> newRestorableContext​(boolean preserveResponseHeaders)
    Returns a supplier that gathers a newStoredContext(boolean) and restores it once the returned supplier is invoked.
    ThreadContext.StoredContext newStoredContext​(boolean preserveResponseHeaders)
    Just like stashContext() but no default context is set.
    java.lang.Runnable preserveContext​(java.lang.Runnable command)
    Saves the current thread context and wraps command in a Runnable that restores that context before running command.
    void putHeader​(java.lang.String key, java.lang.String value)
    Puts a header into the context
    void putHeader​(java.util.Map<java.lang.String,​java.lang.String> header)
    Puts all of the given headers into this context
    void putTransient​(java.lang.String key, java.lang.Object value)
    Puts a transient header object into this context
    void readHeaders​(StreamInput in)
    Reads the headers from the stream into the current context
    static Tuple<java.util.Map<java.lang.String,​java.lang.String>,​java.util.Map<java.lang.String,​java.util.Set<java.lang.String>>> readHeadersFromStream​(StreamInput in)  
    ThreadContext.StoredContext stashAndMergeHeaders​(java.util.Map<java.lang.String,​java.lang.String> headers)
    Removes the current context and resets a new context that contains a merge of the current headers and the given headers.
    ThreadContext.StoredContext stashContext()
    Removes the current context and resets a default context.
    ThreadContext.StoredContext stashWithOrigin​(java.lang.String origin)
    Removes the current context and resets a default context marked with as originating from the supplied string.
    java.lang.Runnable unwrap​(java.lang.Runnable command)
    Unwraps a command that was previously wrapped by preserveContext(Runnable).
    java.util.function.Supplier<ThreadContext.StoredContext> wrapRestorable​(ThreadContext.StoredContext storedContext)
    Same as newRestorableContext(boolean) but wraps an existing context to restore.
    void writeTo​(StreamOutput out)
    Write this into the StreamOutput.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • ThreadContext

      public ThreadContext​(Settings settings)
      Creates a new ThreadContext instance
      Parameters:
      settings - the settings to read the default request headers from
  • Method Details

    • stashContext

      public ThreadContext.StoredContext stashContext()
      Removes the current context and resets a default context. The removed context can be restored by closing the returned ThreadContext.StoredContext.
    • stashWithOrigin

      public ThreadContext.StoredContext stashWithOrigin​(java.lang.String origin)
      Removes the current context and resets a default context marked with as originating from the supplied string. The removed context can be restored by closing the returned ThreadContext.StoredContext. Callers should be careful to save the current context before calling this method and restore it any listeners, likely with ContextPreservingActionListener. Use OriginSettingClient which can be used to do this automatically.

      Without security the origin is ignored, but security uses it to authorize actions that are made up of many sub-actions. These actions call stashWithOrigin(java.lang.String) before performing on behalf of a user that should be allowed even if the user doesn't have permission to perform those actions on their own.

      For example, a user might not have permission to GET from the tasks index but the tasks API will perform a get on their behalf using this method if it can't find the task in memory.

    • stashAndMergeHeaders

      public ThreadContext.StoredContext stashAndMergeHeaders​(java.util.Map<java.lang.String,​java.lang.String> headers)
      Removes the current context and resets a new context that contains a merge of the current headers and the given headers. The removed context can be restored when closing the returned ThreadContext.StoredContext. The merge strategy is that headers that are already existing are preserved unless they are defaults.
    • newStoredContext

      public ThreadContext.StoredContext newStoredContext​(boolean preserveResponseHeaders)
      Just like stashContext() but no default context is set.
      Parameters:
      preserveResponseHeaders - if set to true the response headers of the restore thread will be preserved.
    • newRestorableContext

      public java.util.function.Supplier<ThreadContext.StoredContext> newRestorableContext​(boolean preserveResponseHeaders)
      Returns a supplier that gathers a newStoredContext(boolean) and restores it once the returned supplier is invoked. The context returned from the supplier is a stored version of the suppliers callers context that should be restored once the originally gathered context is not needed anymore. For instance this method should be used like this:
           Supplier<ThreadContext.StoredContext> restorable = context.newRestorableContext(true);
           new Thread() {
               public void run() {
                   try (ThreadContext.StoredContext ctx = restorable.get()) {
                       // execute with the parents context and restore the threads context afterwards
                   }
               }
      
           }.start();
       
      Parameters:
      preserveResponseHeaders - if set to true the response headers of the restore thread will be preserved.
      Returns:
      a restorable context supplier
    • wrapRestorable

      public java.util.function.Supplier<ThreadContext.StoredContext> wrapRestorable​(ThreadContext.StoredContext storedContext)
      Same as newRestorableContext(boolean) but wraps an existing context to restore.
      Parameters:
      storedContext - the context to restore
    • writeTo

      public void writeTo​(StreamOutput out) throws java.io.IOException
      Description copied from interface: Writeable
      Write this into the StreamOutput.
      Specified by:
      writeTo in interface Writeable
      Throws:
      java.io.IOException
    • readHeaders

      public void readHeaders​(StreamInput in) throws java.io.IOException
      Reads the headers from the stream into the current context
      Throws:
      java.io.IOException
    • readHeadersFromStream

      public static Tuple<java.util.Map<java.lang.String,​java.lang.String>,​java.util.Map<java.lang.String,​java.util.Set<java.lang.String>>> readHeadersFromStream​(StreamInput in) throws java.io.IOException
      Throws:
      java.io.IOException
    • getHeader

      public java.lang.String getHeader​(java.lang.String key)
      Returns the header for the given key or null if not present
    • getHeaders

      public java.util.Map<java.lang.String,​java.lang.String> getHeaders()
      Returns all of the request contexts headers
    • getResponseHeaders

      public java.util.Map<java.lang.String,​java.util.List<java.lang.String>> getResponseHeaders()
      Get a copy of all response headers.
      Returns:
      Never null.
    • copyHeaders

      public void copyHeaders​(java.lang.Iterable<java.util.Map.Entry<java.lang.String,​java.lang.String>> headers)
      Copies all header key, value pairs into the current context
    • putHeader

      public void putHeader​(java.lang.String key, java.lang.String value)
      Puts a header into the context
    • putHeader

      public void putHeader​(java.util.Map<java.lang.String,​java.lang.String> header)
      Puts all of the given headers into this context
    • putTransient

      public void putTransient​(java.lang.String key, java.lang.Object value)
      Puts a transient header object into this context
    • getTransient

      public <T> T getTransient​(java.lang.String key)
      Returns a transient header object or null if there is no header for the given key
    • addResponseHeader

      public void addResponseHeader​(java.lang.String key, java.lang.String value)
      Add the value for the specified key Any duplicate value is ignored.
      Parameters:
      key - the header name
      value - the header value
    • addResponseHeader

      public void addResponseHeader​(java.lang.String key, java.lang.String value, java.util.function.Function<java.lang.String,​java.lang.String> uniqueValue)
      Add the value for the specified key with the specified uniqueValue used for de-duplication. Any duplicate value after applying uniqueValue is ignored.
      Parameters:
      key - the header name
      value - the header value
      uniqueValue - the function that produces de-duplication values
    • preserveContext

      public java.lang.Runnable preserveContext​(java.lang.Runnable command)
      Saves the current thread context and wraps command in a Runnable that restores that context before running command. If command has already been passed through this method then it is returned unaltered rather than wrapped twice.
    • unwrap

      public java.lang.Runnable unwrap​(java.lang.Runnable command)
      Unwraps a command that was previously wrapped by preserveContext(Runnable).
    • markAsSystemContext

      public void markAsSystemContext()
      Marks this thread context as an internal system context. This signals that actions in this context are issued by the system itself rather than by a user action.
    • isSystemContext

      public boolean isSystemContext()
      Returns true iff this context is a system context
    • buildDefaultHeaders

      public static java.util.Map<java.lang.String,​java.lang.String> buildDefaultHeaders​(Settings settings)