public final class ThreadContext extends java.lang.Object implements java.io.Closeable, Writeable
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()
Modifier and Type | Class and Description |
---|---|
static interface |
ThreadContext.StoredContext |
Writeable.Reader<V>, Writeable.Writer<V>
Modifier and Type | Field and Description |
---|---|
static Setting<Settings> |
DEFAULT_HEADERS_SETTING |
static java.lang.String |
PREFIX |
Constructor and Description |
---|
ThreadContext(Settings settings)
Creates a new ThreadContext instance
|
Modifier and Type | Method and 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. |
void |
close() |
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.util.Map<java.lang.String,java.lang.String> header)
Puts all of the given headers into this context
|
void |
putHeader(java.lang.String key,
java.lang.String value)
Puts a header into the 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
|
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.
|
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.
|
public static final java.lang.String PREFIX
public ThreadContext(Settings settings)
settings
- the settings to read the default request headers frompublic void close() throws java.io.IOException
close
in interface java.io.Closeable
close
in interface java.lang.AutoCloseable
java.io.IOException
public ThreadContext.StoredContext stashContext()
ThreadContext.StoredContext
public ThreadContext.StoredContext stashAndMergeHeaders(java.util.Map<java.lang.String,java.lang.String> headers)
ThreadContext.StoredContext
. The merge strategy is that headers that are already existing are preserved unless they are defaults.public ThreadContext.StoredContext newStoredContext(boolean preserveResponseHeaders)
stashContext()
but no default context is set.preserveResponseHeaders
- if set to true
the response headers of the restore thread will be preserved.public java.util.function.Supplier<ThreadContext.StoredContext> newRestorableContext(boolean preserveResponseHeaders)
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();
preserveResponseHeaders
- if set to true
the response headers of the restore thread will be preserved.public java.util.function.Supplier<ThreadContext.StoredContext> wrapRestorable(ThreadContext.StoredContext storedContext)
newRestorableContext(boolean)
but wraps an existing context to restore.storedContext
- the context to restorepublic void writeTo(StreamOutput out) throws java.io.IOException
Writeable
public void readHeaders(StreamInput in) throws java.io.IOException
java.io.IOException
public java.lang.String getHeader(java.lang.String key)
null
if not presentpublic java.util.Map<java.lang.String,java.lang.String> getHeaders()
public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResponseHeaders()
null
.public void copyHeaders(java.lang.Iterable<java.util.Map.Entry<java.lang.String,java.lang.String>> headers)
public void putHeader(java.lang.String key, java.lang.String value)
public void putHeader(java.util.Map<java.lang.String,java.lang.String> header)
public void putTransient(java.lang.String key, java.lang.Object value)
public <T> T getTransient(java.lang.String key)
null
if there is no header for the given keypublic void addResponseHeader(java.lang.String key, java.lang.String value)
value
for the specified key
Any duplicate value
is ignored.key
- the header namevalue
- the header valuepublic void addResponseHeader(java.lang.String key, java.lang.String value, java.util.function.Function<java.lang.String,java.lang.String> uniqueValue)
value
for the specified key
with the specified uniqueValue
used for de-duplication. Any duplicate
value
after applying uniqueValue
is ignored.key
- the header namevalue
- the header valueuniqueValue
- the function that produces de-duplication valuespublic java.lang.Runnable preserveContext(java.lang.Runnable command)
command
has already been passed through this method then it is returned unaltered rather than wrapped twice.public java.lang.Runnable unwrap(java.lang.Runnable command)
preserveContext(Runnable)
.public void markAsSystemContext()
public boolean isSystemContext()
true
iff this context is a system context