Class QueryLifecycle

java.lang.Object
org.apache.druid.server.QueryLifecycle

public class QueryLifecycle extends Object
Class that helps a Druid server (broker, historical, etc) manage the lifecycle of a query that it is handling. It ensures that a query goes through the following stages, in the proper order:
  1. Initialization (initialize(Query))
  2. Authorization (authorize(HttpServletRequest)
  3. Execution (execute()
  4. Logging (emitLogsAndMetrics(Throwable, String, long)
Alternatively, if the request is already authenticated and authorized, just call runSimple(Query, AuthenticationResult, AuthorizationResult).

This object is not thread-safe.

  • Constructor Details

  • Method Details

    • runSimple

      public <T> QueryResponse<T> runSimple(Query<T> query, AuthenticationResult authenticationResult, AuthorizationResult authorizationResult)
      For callers who have already authorized their query, and where simplicity is desired over flexibility. This method does it all in one call. Logs and metrics are emitted when the Sequence is either fully iterated or throws an exception.

      The state transitions from NEW, to INITIALIZED, to AUTHORIZING, to AUTHORIZED, to EXECUTING, then DONE.

      Parameters:
      query - the query
      authenticationResult - authentication result indicating identity of the requester
      authorizationResult - authorization result of requester
      Returns:
      results
      Throws:
      DruidException - if the given authorizationResult deny access, which indicates a bug
    • initialize

      public void initialize(Query<?> baseQuery)
      Initializes this object to execute a specific query. Does not actually execute the query.

      The state transitions from NEW, to INITIALIZED.

      Parameters:
      baseQuery - the query
      Throws:
      DruidException - if the current state is not NEW, which indicates a bug
    • authorize

      public AuthorizationResult authorize(javax.servlet.http.HttpServletRequest req)
      Returns AuthorizationResult based on DRUID_AUTHENTICATION_RESULT in the given request, base query would be transformed with restrictions on the AuthorizationResult.

      The state transitions from INITIALIZED, to AUTHORIZING, then to AUTHORIZED or UNAUTHORIZED.

      Note this won't throw exception if authorization deny access or impose policy restrictions. It is the caller's responsibility to throw exception on denial and impose policy restriction.

      Parameters:
      req - HTTP request to be authorized. The auth-related fields in the HTTP request will be set.
      Returns:
      authorization result denoting whether the query is authorized or not, along with policy restrictions
      Throws:
      IllegalStateException - if the request was not authenticated
      DruidException - if the current state is not INITIALIZED, which indicates a bug
    • authorize

      public AuthorizationResult authorize(AuthenticationResult authenticationResult)
      Returns AuthorizationResult based on the given AuthenticationResult, base query would be transformed with restrictions on the AuthorizationResult.

      The state transitions from INITIALIZED, to AUTHORIZING, then to AUTHORIZED or UNAUTHORIZED.

      Note this won't throw exception if authorization deny access or impose policy restrictions. It is the caller's responsibility to throw exception on denial and impose policy restriction.

      This method is to be used by the grpc-query-extension.

      Parameters:
      authenticationResult - authentication result indicating identity of the requester
      Returns:
      authorization result denoting whether the query is authorized or not, along with policy restrictions.
      Throws:
      DruidException - if the current state is not INITIALIZED, which indicates a bug
    • execute

      public <T> QueryResponse<T> execute()
      Executes the query.

      Note that query logs and metrics will not be emitted automatically when the Sequence is fully iterated withou. It is the caller's responsibility to call emitLogsAndMetrics(Throwable, String, long) to emit logs and metrics.

      The state transitions from AUTHORIZED, to EXECUTING.

      Returns:
      result sequence and response context
      Throws:
      DruidException - if the current state is not AUTHORIZED, which indicates a bug
    • emitLogsAndMetrics

      public void emitLogsAndMetrics(@Nullable Throwable e, @Nullable String remoteAddress, long bytesWritten)
      Emits logs and metrics for this query.

      The state transitions to DONE. The initial state can be anything, but it likely shouldn't be set to DONE.

      If baseQuery is null, likely because initialize(Query) was never call, do nothing.

      Parameters:
      e - exception that occurred while processing this query
      remoteAddress - remote address, for logging; or null if unknown
      bytesWritten - number of bytes written; will become a query/bytes metric if >= 0
    • getQuery

      @Nullable public Query<?> getQuery()
    • getQueryId

      public String getQueryId()
    • threadName

      public String threadName(String currThreadName)
    • newOutputWriter

      public com.fasterxml.jackson.databind.ObjectMapper newOutputWriter(ResourceIOReaderWriterFactory.ResourceIOReaderWriter ioReaderWriter)
    • getToolChest

      public QueryToolChest getToolChest()
    • shouldLogStackTrace

      public static boolean shouldLogStackTrace(Throwable e, QueryContext queryContext)
      Returns whether stack traces should be logged for a particular exception thrown with a particular query context. Stack traces are logged if QueryContext.isDebug(), or if the DruidException.Persona is DruidException.Persona.DEVELOPER or DruidException.Persona.OPERATOR. The idea is that other personas are meant to interact with the API, not with code or logs, so logging stack traces by default adds clutter that is not very helpful.
      Parameters:
      e - exception
      queryContext - query context