Class ThreadContext
- All Implemented Interfaces:
Writeable
public final class ThreadContext extends java.lang.Object implements 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()
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceThreadContext.StoredContextNested 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.StringACTION_ORIGIN_TRANSIENT_NAMEName for theoriginattribute.static Setting<Settings>DEFAULT_HEADERS_SETTINGstatic java.lang.StringPREFIX -
Constructor Summary
Constructors Constructor Description ThreadContext(Settings settings)Creates a new ThreadContext instance -
Method Summary
Modifier and Type Method Description voidaddResponseHeader(java.lang.String key, java.lang.String value)Add thevaluefor the specifiedkeyAny duplicatevalueis ignored.voidaddResponseHeader(java.lang.String key, java.lang.String value, java.util.function.Function<java.lang.String,java.lang.String> uniqueValue)Add thevaluefor the specifiedkeywith the specifieduniqueValueused for de-duplication.static java.util.Map<java.lang.String,java.lang.String>buildDefaultHeaders(Settings settings)WriteablecaptureAsWriteable()Captures the current thread context as writeable, allowing it to be serialized out latervoidcopyHeaders(java.lang.Iterable<java.util.Map.Entry<java.lang.String,java.lang.String>> headers)Copies all header key, value pairs into the current contextjava.lang.StringgetHeader(java.lang.String key)Returns the header for the given key ornullif not presentjava.util.Map<java.lang.String,java.lang.String>getHeaders()Returns all of the request headers from the thread's context.
Be advised, headers might contain credentials. In order to avoid storing, and erroneously exposing, such headers, it is recommended to instead store security headers that prove the credentials have been verified successfully, and which are internal to the system, in the sense that they cannot be sent by the clients.java.util.Map<java.lang.String,java.lang.String>getRequestHeadersOnly()Returns the request headers, without the default headersjava.util.Map<java.lang.String,java.util.List<java.lang.String>>getResponseHeaders()Get a copy of all response headers.<T> TgetTransient(java.lang.String key)Returns a transient header object ornullif there is no header for the given keybooleanisSystemContext()Returnstrueiff this context is a system contextvoidmarkAsSystemContext()Marks this thread context as an internal system context.java.util.function.Supplier<ThreadContext.StoredContext>newRestorableContext(boolean preserveResponseHeaders)Returns a supplier that gathers anewStoredContext(boolean)and restores it once the returned supplier is invoked.ThreadContext.StoredContextnewStoredContext(boolean preserveResponseHeaders)Just likestashContext()but no default context is set.ThreadContext.StoredContextnewStoredContext(boolean preserveResponseHeaders, java.util.Collection<java.lang.String> transientHeadersToClear)Just likestashContext()but no default context is set.java.lang.RunnablepreserveContext(java.lang.Runnable command)Saves the current thread context and wraps command in a Runnable that restores that context before running command.voidputHeader(java.lang.String key, java.lang.String value)Puts a header into the contextvoidputHeader(java.util.Map<java.lang.String,java.lang.String> header)Puts all of the given headers into this contextvoidputTransient(java.lang.String key, java.lang.Object value)Puts a transient header object into this contextvoidreadHeaders(StreamInput in)Reads the headers from the stream into the current contextstatic org.elasticsearch.common.collect.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)voidsetHeaders(org.elasticsearch.common.collect.Tuple<java.util.Map<java.lang.String,java.lang.String>,java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> headerTuple)ThreadContext.StoredContextstashAndMergeHeaders(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.StoredContextstashContext()Removes the current context and resets a default context.ThreadContext.StoredContextstashWithOrigin(java.lang.String origin)Removes the current context and resets a default context marked with as originating from the supplied string.java.lang.Runnableunwrap(java.lang.Runnable command)Unwraps a command that was previously wrapped bypreserveContext(Runnable).java.util.function.Supplier<ThreadContext.StoredContext>wrapRestorable(ThreadContext.StoredContext storedContext)Same asnewRestorableContext(boolean)but wraps an existing context to restore.voidwriteTo(StreamOutput out)Write this into the StreamOutput.
-
Field Details
-
PREFIX
public static final java.lang.String PREFIX- See Also:
- Constant Field Values
-
DEFAULT_HEADERS_SETTING
-
ACTION_ORIGIN_TRANSIENT_NAME
public static final java.lang.String ACTION_ORIGIN_TRANSIENT_NAMEName for theoriginattribute.- See Also:
- Constant Field Values
-
-
Constructor Details
-
ThreadContext
Creates a new ThreadContext instance- Parameters:
settings- the settings to read the default request headers from
-
-
Method Details
-
stashContext
Removes the current context and resets a default context. The removed context can be restored by closing the returnedThreadContext.StoredContext. -
captureAsWriteable
Captures the current thread context as writeable, allowing it to be serialized out later -
stashWithOrigin
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 returnedThreadContext.StoredContext. Callers should be careful to save the current context before calling this method and restore it any listeners, likely withContextPreservingActionListener. UseOriginSettingClientwhich 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 returnedThreadContext.StoredContext. The merge strategy is that headers that are already existing are preserved unless they are defaults. -
newStoredContext
Just likestashContext()but no default context is set.- Parameters:
preserveResponseHeaders- if set totruethe response headers of the restore thread will be preserved.
-
newStoredContext
public ThreadContext.StoredContext newStoredContext(boolean preserveResponseHeaders, java.util.Collection<java.lang.String> transientHeadersToClear)Just likestashContext()but no default context is set. Instead, thetransientHeadersToClearargument can be used to clear specific transient headers in the new context. All headers (with the possible exception ofresponseHeaders) are restored by closing the returnedThreadContext.StoredContext.- Parameters:
preserveResponseHeaders- if set totruethe 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 anewStoredContext(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 totruethe 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 asnewRestorableContext(boolean)but wraps an existing context to restore.- Parameters:
storedContext- the context to restore
-
writeTo
Description copied from interface:WriteableWrite this into the StreamOutput. -
readHeaders
Reads the headers from the stream into the current context- Throws:
java.io.IOException
-
setHeaders
public void setHeaders(org.elasticsearch.common.collect.Tuple<java.util.Map<java.lang.String,java.lang.String>,java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> headerTuple) -
readHeadersFromStream
public static org.elasticsearch.common.collect.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 ornullif not present -
getHeaders
public java.util.Map<java.lang.String,java.lang.String> getHeaders()Returns all of the request headers from the thread's context.
Be advised, headers might contain credentials. In order to avoid storing, and erroneously exposing, such headers, it is recommended to instead store security headers that prove the credentials have been verified successfully, and which are internal to the system, in the sense that they cannot be sent by the clients. -
getRequestHeadersOnly
public java.util.Map<java.lang.String,java.lang.String> getRequestHeadersOnly()Returns the request headers, without the default 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 ornullif there is no header for the given key -
addResponseHeader
public void addResponseHeader(java.lang.String key, java.lang.String value)Add thevaluefor the specifiedkeyAny duplicatevalueis ignored.- Parameters:
key- the header namevalue- 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 thevaluefor the specifiedkeywith the specifieduniqueValueused for de-duplication. Any duplicatevalueafter applyinguniqueValueis ignored.- Parameters:
key- the header namevalue- the header valueuniqueValue- 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. Ifcommandhas 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 bypreserveContext(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()Returnstrueiff this context is a system context -
buildDefaultHeaders
public static java.util.Map<java.lang.String,java.lang.String> buildDefaultHeaders(Settings settings)
-