github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/api/v1/options/handler.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  // Package options configures query http handlers.
    22  package options
    23  
    24  import (
    25  	"io"
    26  	"net/http"
    27  	"strings"
    28  	"time"
    29  
    30  	clusterclient "github.com/m3db/m3/src/cluster/client"
    31  	placementhandleroptions "github.com/m3db/m3/src/cluster/placementhandler/handleroptions"
    32  	"github.com/m3db/m3/src/cmd/services/m3coordinator/ingest"
    33  	dbconfig "github.com/m3db/m3/src/cmd/services/m3dbnode/config"
    34  	"github.com/m3db/m3/src/cmd/services/m3query/config"
    35  	"github.com/m3db/m3/src/dbnode/encoding"
    36  	dbnamespace "github.com/m3db/m3/src/dbnode/namespace"
    37  	"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
    38  	"github.com/m3db/m3/src/query/api/v1/middleware"
    39  	"github.com/m3db/m3/src/query/api/v1/validators"
    40  	"github.com/m3db/m3/src/query/executor"
    41  	graphite "github.com/m3db/m3/src/query/graphite/storage"
    42  	"github.com/m3db/m3/src/query/models"
    43  	"github.com/m3db/m3/src/query/storage"
    44  	"github.com/m3db/m3/src/query/storage/m3"
    45  	"github.com/m3db/m3/src/query/ts"
    46  	"github.com/m3db/m3/src/x/clock"
    47  	"github.com/m3db/m3/src/x/instrument"
    48  
    49  	"github.com/prometheus/prometheus/promql"
    50  	"google.golang.org/protobuf/runtime/protoiface"
    51  )
    52  
    53  // QueryEngine is a type of query engine.
    54  type QueryEngine string
    55  
    56  const (
    57  	// PrometheusEngine is the prometheus query engine type.
    58  	PrometheusEngine QueryEngine = "prometheus"
    59  	// M3QueryEngine is M3 query engine type.
    60  	M3QueryEngine QueryEngine = "m3query"
    61  )
    62  
    63  // PromQLEngineFn constructs promql.Engine with the given lookbackDuration. promql.Engine uses
    64  // a fixed lookback, so we have to create multiple engines for different lookback values.
    65  //
    66  // TODO(vilius): there's a conversation at Prometheus mailing list about making lookback dynamic
    67  //   https://groups.google.com/g/prometheus-developers/c/9wzuobfLMV8
    68  type PromQLEngineFn func(lookbackDuration time.Duration) (*promql.Engine, error)
    69  
    70  // OptionTransformFn transforms given handler options.
    71  type OptionTransformFn func(opts HandlerOptions) HandlerOptions
    72  
    73  // CustomHandlerOptions is a list of custom handler options.
    74  type CustomHandlerOptions struct {
    75  	CustomHandlers    []CustomHandler
    76  	OptionTransformFn OptionTransformFn
    77  }
    78  
    79  // CustomHandler allows for custom third party http handlers.
    80  type CustomHandler interface {
    81  	// Route is the custom handler route.
    82  	Route() string
    83  	// Methods is the list of http methods this handler services.
    84  	Methods() []string
    85  	// Handler is the custom handler itself.
    86  	// prev is optional argument for getting already registered handler for the same route.
    87  	// If there is nothing to override, prev will be nil.
    88  	Handler(handlerOptions HandlerOptions, prev http.Handler) (http.Handler, error)
    89  	// MiddlewareOverride is a function to override the global middleware configuration for the route.
    90  	// If this CustomHandler is overriding an existing handler, the MiddlewareOverride for the existing handler is first
    91  	// applied before applying this function.
    92  	MiddlewareOverride() middleware.OverrideOptions
    93  }
    94  
    95  // QueryRouter is responsible for routing queries between promql and m3query.
    96  type QueryRouter interface {
    97  	Setup(opts QueryRouterOptions)
    98  	ServeHTTP(w http.ResponseWriter, req *http.Request)
    99  }
   100  
   101  // QueryRouterOptions defines options for QueryRouter
   102  type QueryRouterOptions struct {
   103  	DefaultQueryEngine QueryEngine
   104  	PromqlHandler      func(http.ResponseWriter, *http.Request)
   105  	M3QueryHandler     func(http.ResponseWriter, *http.Request)
   106  }
   107  
   108  // GraphiteRenderRouter is responsible for routing graphite render queries.
   109  type GraphiteRenderRouter interface {
   110  	Setup(opts GraphiteRenderRouterOptions)
   111  	ServeHTTP(w http.ResponseWriter, req *http.Request)
   112  }
   113  
   114  // GraphiteRenderRouterOptions defines options for the graphite render router.
   115  type GraphiteRenderRouterOptions struct {
   116  	RenderHandler func(http.ResponseWriter, *http.Request)
   117  }
   118  
   119  // GraphiteFindRouter is responsible for routing graphite find queries.
   120  type GraphiteFindRouter interface {
   121  	Setup(opts GraphiteFindRouterOptions)
   122  	ServeHTTP(w http.ResponseWriter, req *http.Request)
   123  }
   124  
   125  // GraphiteFindRouterOptions defines options for graphite find router
   126  type GraphiteFindRouterOptions struct {
   127  	FindHandler func(http.ResponseWriter, *http.Request)
   128  }
   129  
   130  // RemoteReadRenderer renders remote read output.
   131  type RemoteReadRenderer func(io.Writer, []*ts.Series,
   132  	models.RequestParams, bool)
   133  
   134  // HandlerOptions represents handler options.
   135  type HandlerOptions interface {
   136  	// CreatedAt returns the time the options were created.
   137  	CreatedAt() time.Time
   138  
   139  	// Storage returns the set storage.
   140  	Storage() storage.Storage
   141  	// SetStorage sets the set storage.
   142  	SetStorage(s storage.Storage) HandlerOptions
   143  
   144  	// DownsamplerAndWriter returns the set downsampler and writer.
   145  	DownsamplerAndWriter() ingest.DownsamplerAndWriter
   146  	// SetDownsamplerAndWriter sets the set downsampler and writer.
   147  	SetDownsamplerAndWriter(d ingest.DownsamplerAndWriter) HandlerOptions
   148  
   149  	// Engine returns the engine.
   150  	Engine() executor.Engine
   151  	// SetEngine sets the engine.
   152  	SetEngine(e executor.Engine) HandlerOptions
   153  
   154  	// PrometheusEngineFn returns the function for Prometheus engine creation.
   155  	PrometheusEngineFn() PromQLEngineFn
   156  	// SetPrometheusEngineFn sets the function for Prometheus engine creation.
   157  	SetPrometheusEngineFn(fn PromQLEngineFn) HandlerOptions
   158  
   159  	// Clusters returns the clusters.
   160  	Clusters() m3.Clusters
   161  	// SetClusters sets the clusters.
   162  	SetClusters(c m3.Clusters) HandlerOptions
   163  
   164  	// ClusterClient returns the cluster client.
   165  	ClusterClient() clusterclient.Client
   166  	// SetClusterClient sets the cluster client.
   167  	SetClusterClient(c clusterclient.Client) HandlerOptions
   168  
   169  	// Config returns the config.
   170  	Config() config.Configuration
   171  	// SetConfig sets the config.
   172  	SetConfig(c config.Configuration) HandlerOptions
   173  
   174  	// EmbeddedDBCfg returns the embedded db config.
   175  	EmbeddedDBCfg() *dbconfig.DBConfiguration
   176  	// SetEmbeddedDBCfg sets the embedded db config.
   177  	SetEmbeddedDBCfg(c *dbconfig.DBConfiguration) HandlerOptions
   178  
   179  	// TagOptions returns the tag options.
   180  	TagOptions() models.TagOptions
   181  	// SetTagOptions sets the tag options.
   182  	SetTagOptions(opts models.TagOptions) HandlerOptions
   183  
   184  	// FetchOptionsBuilder returns the fetch options builder.
   185  	FetchOptionsBuilder() handleroptions.FetchOptionsBuilder
   186  	// SetFetchOptionsBuilder sets the fetch options builder.
   187  	SetFetchOptionsBuilder(b handleroptions.FetchOptionsBuilder) HandlerOptions
   188  
   189  	// QueryContextOptions returns the query context options.
   190  	QueryContextOptions() models.QueryContextOptions
   191  	// SetQueryContextOptions sets the query context options.
   192  	SetQueryContextOptions(o models.QueryContextOptions) HandlerOptions
   193  
   194  	// CPUProfileDuration returns the cpu profile duration.
   195  	CPUProfileDuration() time.Duration
   196  	// SetCPUProfileDuration sets the cpu profile duration.
   197  	SetCPUProfileDuration(c time.Duration) HandlerOptions
   198  
   199  	// ServiceOptionDefaults returns the service option defaults.
   200  	ServiceOptionDefaults() []placementhandleroptions.ServiceOptionsDefault
   201  	// SetServiceOptionDefaults sets the service option defaults.
   202  	SetServiceOptionDefaults(s []placementhandleroptions.ServiceOptionsDefault) HandlerOptions
   203  
   204  	// NowFn returns the now function.
   205  	NowFn() clock.NowFn
   206  	// SetNowFn sets the now function.
   207  	SetNowFn(f clock.NowFn) HandlerOptions
   208  
   209  	// InstrumentOpts returns the instrumentation options.
   210  	InstrumentOpts() instrument.Options
   211  	// SetInstrumentOpts sets instrumentation options.
   212  	SetInstrumentOpts(opts instrument.Options) HandlerOptions
   213  
   214  	// DefaultQueryEngine returns the default query engine.
   215  	DefaultQueryEngine() QueryEngine
   216  	// SetDefaultQueryEngine returns the default query engine.
   217  	SetDefaultQueryEngine(value QueryEngine) HandlerOptions
   218  
   219  	// QueryRouter is a reference to the router which is responsible for routing
   220  	// queries between PromQL and M3Query.
   221  	QueryRouter() QueryRouter
   222  	// SetQueryRouter sets query router.
   223  	SetQueryRouter(value QueryRouter) HandlerOptions
   224  
   225  	// InstantQueryRouter is a reference to the router which is responsible for
   226  	// routing instant queries between PromQL and M3Query.
   227  	InstantQueryRouter() QueryRouter
   228  	// SetInstantQueryRouter sets query router for instant queries.
   229  	SetInstantQueryRouter(value QueryRouter) HandlerOptions
   230  
   231  	// GraphiteStorageOptions returns the Graphite storage options.
   232  	GraphiteStorageOptions() graphite.M3WrappedStorageOptions
   233  	// SetGraphiteStorageOptions sets the Graphite storage options.
   234  	SetGraphiteStorageOptions(value graphite.M3WrappedStorageOptions) HandlerOptions
   235  
   236  	// GraphiteFindFetchOptionsBuilder returns the Graphite find fetch options builder.
   237  	GraphiteFindFetchOptionsBuilder() handleroptions.FetchOptionsBuilder
   238  	// SetGraphiteFindFetchOptionsBuilder sets the Graphite find fetch options builder.
   239  	SetGraphiteFindFetchOptionsBuilder(value handleroptions.FetchOptionsBuilder) HandlerOptions
   240  
   241  	// GraphiteRenderFetchOptionsBuilder returns the Graphite render fetch options builder.
   242  	GraphiteRenderFetchOptionsBuilder() handleroptions.FetchOptionsBuilder
   243  	// SetGraphiteRenderFetchOptionsBuilder sets the Graphite render fetch options builder.
   244  	SetGraphiteRenderFetchOptionsBuilder(value handleroptions.FetchOptionsBuilder) HandlerOptions
   245  
   246  	// GraphiteRenderRouter is a reference to the router for graphite render queries.
   247  	GraphiteRenderRouter() GraphiteRenderRouter
   248  	// SetGraphiteRenderRouter sets the graphite render router.
   249  	SetGraphiteRenderRouter(value GraphiteRenderRouter) HandlerOptions
   250  
   251  	// GraphiteFindRouter is a reference to the router for graphite find queries.
   252  	GraphiteFindRouter() GraphiteFindRouter
   253  	// SetGraphiteFindRouter sets the graphite find router.
   254  	SetGraphiteFindRouter(value GraphiteFindRouter) HandlerOptions
   255  
   256  	// SetM3DBOptions sets the M3DB options.
   257  	SetM3DBOptions(value m3.Options) HandlerOptions
   258  	// M3DBOptions returns the M3DB options.
   259  	M3DBOptions() m3.Options
   260  
   261  	// SetStoreMetricsType enables/disables storing of metrics type.
   262  	SetStoreMetricsType(value bool) HandlerOptions
   263  	// StoreMetricsType returns true if storing of metrics type is enabled.
   264  	StoreMetricsType() bool
   265  
   266  	// SetNamespaceValidator sets the NamespaceValidator.
   267  	SetNamespaceValidator(NamespaceValidator) HandlerOptions
   268  	// NamespaceValidator returns the NamespaceValidator.
   269  	NamespaceValidator() NamespaceValidator
   270  
   271  	// SetKVStoreProtoParser sets the KVStoreProtoParser.
   272  	SetKVStoreProtoParser(KVStoreProtoParser) HandlerOptions
   273  	// KVStoreProtoParser returns the KVStoreProtoParser.
   274  	KVStoreProtoParser() KVStoreProtoParser
   275  
   276  	// SetRegisterMiddleware sets the function to construct the set of Middleware functions to run.
   277  	SetRegisterMiddleware(value middleware.Register) HandlerOptions
   278  	// RegisterMiddleware returns the function to construct the set of Middleware functions to run.
   279  	RegisterMiddleware() middleware.Register
   280  
   281  	// DefaultLookback returns the default value of lookback duration.
   282  	DefaultLookback() time.Duration
   283  	// SetDefaultLookback sets the default value of lookback duration.
   284  	SetDefaultLookback(value time.Duration) HandlerOptions
   285  }
   286  
   287  // HandlerOptions represents handler options.
   288  type handlerOptions struct {
   289  	storage                           storage.Storage
   290  	downsamplerAndWriter              ingest.DownsamplerAndWriter
   291  	engine                            executor.Engine
   292  	prometheusEngineFn                PromQLEngineFn
   293  	defaultEngine                     QueryEngine
   294  	clusters                          m3.Clusters
   295  	clusterClient                     clusterclient.Client
   296  	config                            config.Configuration
   297  	embeddedDBCfg                     *dbconfig.DBConfiguration
   298  	createdAt                         time.Time
   299  	tagOptions                        models.TagOptions
   300  	fetchOptionsBuilder               handleroptions.FetchOptionsBuilder
   301  	queryContextOptions               models.QueryContextOptions
   302  	instrumentOpts                    instrument.Options
   303  	cpuProfileDuration                time.Duration
   304  	serviceOptionDefaults             []placementhandleroptions.ServiceOptionsDefault
   305  	nowFn                             clock.NowFn
   306  	queryRouter                       QueryRouter
   307  	instantQueryRouter                QueryRouter
   308  	graphiteStorageOpts               graphite.M3WrappedStorageOptions
   309  	graphiteFindFetchOptionsBuilder   handleroptions.FetchOptionsBuilder
   310  	graphiteRenderFetchOptionsBuilder handleroptions.FetchOptionsBuilder
   311  	m3dbOpts                          m3.Options
   312  	namespaceValidator                NamespaceValidator
   313  	storeMetricsType                  bool
   314  	kvStoreProtoParser                KVStoreProtoParser
   315  	registerMiddleware                middleware.Register
   316  	graphiteRenderRouter              GraphiteRenderRouter
   317  	graphiteFindRouter                GraphiteFindRouter
   318  	defaultLookback                   time.Duration
   319  }
   320  
   321  // EmptyHandlerOptions returns  default handler options.
   322  func EmptyHandlerOptions() HandlerOptions {
   323  	return &handlerOptions{
   324  		instrumentOpts: instrument.NewOptions(),
   325  		nowFn:          time.Now,
   326  		m3dbOpts:       m3.NewOptions(encoding.NewOptions()),
   327  	}
   328  }
   329  
   330  // NewHandlerOptions builds a handler options.
   331  func NewHandlerOptions(
   332  	downsamplerAndWriter ingest.DownsamplerAndWriter,
   333  	tagOptions models.TagOptions,
   334  	engine executor.Engine,
   335  	prometheusEngineFn PromQLEngineFn,
   336  	m3dbClusters m3.Clusters,
   337  	clusterClient clusterclient.Client,
   338  	cfg config.Configuration,
   339  	embeddedDBCfg *dbconfig.DBConfiguration,
   340  	fetchOptionsBuilder handleroptions.FetchOptionsBuilder,
   341  	graphiteFindFetchOptionsBuilder handleroptions.FetchOptionsBuilder,
   342  	graphiteRenderFetchOptionsBuilder handleroptions.FetchOptionsBuilder,
   343  	queryContextOptions models.QueryContextOptions,
   344  	instrumentOpts instrument.Options,
   345  	cpuProfileDuration time.Duration,
   346  	serviceOptionDefaults []placementhandleroptions.ServiceOptionsDefault,
   347  	queryRouter QueryRouter,
   348  	instantQueryRouter QueryRouter,
   349  	graphiteStorageOpts graphite.M3WrappedStorageOptions,
   350  	m3dbOpts m3.Options,
   351  	graphiteRenderRouter GraphiteRenderRouter,
   352  	graphiteFindRouter GraphiteFindRouter,
   353  	defaultLookback time.Duration,
   354  ) (HandlerOptions, error) {
   355  	storeMetricsType := false
   356  	if cfg.StoreMetricsType != nil {
   357  		storeMetricsType = *cfg.StoreMetricsType
   358  	}
   359  	return &handlerOptions{
   360  		storage:                           downsamplerAndWriter.Storage(),
   361  		downsamplerAndWriter:              downsamplerAndWriter,
   362  		engine:                            engine,
   363  		prometheusEngineFn:                prometheusEngineFn,
   364  		defaultEngine:                     getDefaultQueryEngine(cfg.Query.DefaultEngine),
   365  		clusters:                          m3dbClusters,
   366  		clusterClient:                     clusterClient,
   367  		config:                            cfg,
   368  		embeddedDBCfg:                     embeddedDBCfg,
   369  		createdAt:                         time.Now(),
   370  		tagOptions:                        tagOptions,
   371  		fetchOptionsBuilder:               fetchOptionsBuilder,
   372  		graphiteFindFetchOptionsBuilder:   graphiteFindFetchOptionsBuilder,
   373  		graphiteRenderFetchOptionsBuilder: graphiteRenderFetchOptionsBuilder,
   374  		queryContextOptions:               queryContextOptions,
   375  		instrumentOpts:                    instrumentOpts,
   376  		cpuProfileDuration:                cpuProfileDuration,
   377  		serviceOptionDefaults:             serviceOptionDefaults,
   378  		nowFn:                             time.Now,
   379  		queryRouter:                       queryRouter,
   380  		instantQueryRouter:                instantQueryRouter,
   381  		graphiteStorageOpts:               graphiteStorageOpts,
   382  		m3dbOpts:                          m3dbOpts,
   383  		storeMetricsType:                  storeMetricsType,
   384  		namespaceValidator:                validators.NamespaceValidator,
   385  		registerMiddleware:                middleware.Default,
   386  		graphiteRenderRouter:              graphiteRenderRouter,
   387  		graphiteFindRouter:                graphiteFindRouter,
   388  		defaultLookback:                   defaultLookback,
   389  	}, nil
   390  }
   391  
   392  func (o *handlerOptions) CreatedAt() time.Time {
   393  	return o.createdAt
   394  }
   395  
   396  func (o *handlerOptions) Storage() storage.Storage {
   397  	return o.storage
   398  }
   399  
   400  func (o *handlerOptions) SetStorage(s storage.Storage) HandlerOptions {
   401  	opts := *o
   402  	opts.storage = s
   403  	return &opts
   404  }
   405  
   406  func (o *handlerOptions) DownsamplerAndWriter() ingest.DownsamplerAndWriter {
   407  	return o.downsamplerAndWriter
   408  }
   409  
   410  func (o *handlerOptions) SetDownsamplerAndWriter(
   411  	d ingest.DownsamplerAndWriter) HandlerOptions {
   412  	opts := *o
   413  	opts.downsamplerAndWriter = d
   414  	return &opts
   415  }
   416  
   417  func (o *handlerOptions) Engine() executor.Engine {
   418  	return o.engine
   419  }
   420  
   421  func (o *handlerOptions) SetEngine(e executor.Engine) HandlerOptions {
   422  	opts := *o
   423  	opts.engine = e
   424  	return &opts
   425  }
   426  
   427  func (o *handlerOptions) PrometheusEngineFn() PromQLEngineFn {
   428  	return o.prometheusEngineFn
   429  }
   430  
   431  func (o *handlerOptions) SetPrometheusEngineFn(fn PromQLEngineFn) HandlerOptions {
   432  	opts := *o
   433  	opts.prometheusEngineFn = fn
   434  	return &opts
   435  }
   436  
   437  func (o *handlerOptions) Clusters() m3.Clusters {
   438  	return o.clusters
   439  }
   440  
   441  func (o *handlerOptions) SetClusters(c m3.Clusters) HandlerOptions {
   442  	opts := *o
   443  	opts.clusters = c
   444  	return &opts
   445  }
   446  
   447  func (o *handlerOptions) ClusterClient() clusterclient.Client {
   448  	return o.clusterClient
   449  }
   450  
   451  func (o *handlerOptions) SetClusterClient(
   452  	c clusterclient.Client) HandlerOptions {
   453  	opts := *o
   454  	opts.clusterClient = c
   455  	return &opts
   456  }
   457  
   458  func (o *handlerOptions) Config() config.Configuration {
   459  	return o.config
   460  }
   461  
   462  func (o *handlerOptions) SetConfig(c config.Configuration) HandlerOptions {
   463  	opts := *o
   464  	opts.config = c
   465  	return &opts
   466  }
   467  
   468  func (o *handlerOptions) EmbeddedDBCfg() *dbconfig.DBConfiguration {
   469  	return o.embeddedDBCfg
   470  }
   471  
   472  func (o *handlerOptions) SetEmbeddedDBCfg(
   473  	c *dbconfig.DBConfiguration) HandlerOptions {
   474  	opts := *o
   475  	opts.embeddedDBCfg = c
   476  	return &opts
   477  }
   478  
   479  func (o *handlerOptions) TagOptions() models.TagOptions {
   480  	return o.tagOptions
   481  }
   482  
   483  func (o *handlerOptions) SetTagOptions(tags models.TagOptions) HandlerOptions {
   484  	opts := *o
   485  	opts.tagOptions = tags
   486  	return &opts
   487  }
   488  
   489  func (o *handlerOptions) FetchOptionsBuilder() handleroptions.FetchOptionsBuilder {
   490  	return o.fetchOptionsBuilder
   491  }
   492  
   493  func (o *handlerOptions) SetFetchOptionsBuilder(
   494  	b handleroptions.FetchOptionsBuilder) HandlerOptions {
   495  	opts := *o
   496  	opts.fetchOptionsBuilder = b
   497  	return &opts
   498  }
   499  
   500  func (o *handlerOptions) QueryContextOptions() models.QueryContextOptions {
   501  	return o.queryContextOptions
   502  }
   503  
   504  func (o *handlerOptions) SetQueryContextOptions(
   505  	q models.QueryContextOptions) HandlerOptions {
   506  	opts := *o
   507  	opts.queryContextOptions = q
   508  	return &opts
   509  }
   510  
   511  func (o *handlerOptions) CPUProfileDuration() time.Duration {
   512  	return o.cpuProfileDuration
   513  }
   514  
   515  func (o *handlerOptions) SetCPUProfileDuration(
   516  	c time.Duration) HandlerOptions {
   517  	opts := *o
   518  	opts.cpuProfileDuration = c
   519  	return &opts
   520  }
   521  
   522  func (o *handlerOptions) ServiceOptionDefaults() []placementhandleroptions.ServiceOptionsDefault {
   523  	return o.serviceOptionDefaults
   524  }
   525  
   526  func (o *handlerOptions) SetServiceOptionDefaults(
   527  	s []placementhandleroptions.ServiceOptionsDefault) HandlerOptions {
   528  	opts := *o
   529  	opts.serviceOptionDefaults = s
   530  	return &opts
   531  }
   532  
   533  func (o *handlerOptions) InstrumentOpts() instrument.Options {
   534  	return o.instrumentOpts
   535  }
   536  
   537  func (o *handlerOptions) SetInstrumentOpts(opts instrument.Options) HandlerOptions {
   538  	options := *o
   539  	options.instrumentOpts = opts
   540  	return &options
   541  }
   542  
   543  func (o *handlerOptions) NowFn() clock.NowFn {
   544  	return o.nowFn
   545  }
   546  
   547  func (o *handlerOptions) SetNowFn(n clock.NowFn) HandlerOptions {
   548  	options := *o
   549  	options.nowFn = n
   550  	return &options
   551  }
   552  
   553  func (o *handlerOptions) DefaultQueryEngine() QueryEngine {
   554  	return o.defaultEngine
   555  }
   556  
   557  func (o *handlerOptions) SetDefaultQueryEngine(value QueryEngine) HandlerOptions {
   558  	options := *o
   559  	options.defaultEngine = value
   560  	return &options
   561  }
   562  
   563  func getDefaultQueryEngine(cfgEngine string) QueryEngine {
   564  	engine := PrometheusEngine
   565  	if strings.ToLower(cfgEngine) == string(M3QueryEngine) {
   566  		engine = M3QueryEngine
   567  	}
   568  	return engine
   569  }
   570  
   571  // IsQueryEngineSet returns true if value contains query engine value. Otherwise returns false.
   572  func IsQueryEngineSet(v string) bool {
   573  	if strings.ToLower(v) == string(PrometheusEngine) ||
   574  		strings.ToLower(v) == string(M3QueryEngine) {
   575  		return true
   576  	}
   577  	return false
   578  }
   579  
   580  func (o *handlerOptions) QueryRouter() QueryRouter {
   581  	return o.queryRouter
   582  }
   583  
   584  func (o *handlerOptions) SetQueryRouter(value QueryRouter) HandlerOptions {
   585  	opts := *o
   586  	opts.queryRouter = value
   587  	return &opts
   588  }
   589  
   590  func (o *handlerOptions) InstantQueryRouter() QueryRouter {
   591  	return o.instantQueryRouter
   592  }
   593  
   594  func (o *handlerOptions) SetInstantQueryRouter(value QueryRouter) HandlerOptions {
   595  	opts := *o
   596  	opts.instantQueryRouter = value
   597  	return &opts
   598  }
   599  
   600  func (o *handlerOptions) GraphiteStorageOptions() graphite.M3WrappedStorageOptions {
   601  	return o.graphiteStorageOpts
   602  }
   603  
   604  func (o *handlerOptions) SetGraphiteStorageOptions(value graphite.M3WrappedStorageOptions) HandlerOptions {
   605  	opts := *o
   606  	opts.graphiteStorageOpts = value
   607  	return &opts
   608  }
   609  
   610  func (o *handlerOptions) GraphiteFindFetchOptionsBuilder() handleroptions.FetchOptionsBuilder {
   611  	return o.graphiteFindFetchOptionsBuilder
   612  }
   613  
   614  func (o *handlerOptions) SetGraphiteFindFetchOptionsBuilder(value handleroptions.FetchOptionsBuilder) HandlerOptions {
   615  	opts := *o
   616  	opts.graphiteFindFetchOptionsBuilder = value
   617  	return &opts
   618  }
   619  
   620  func (o *handlerOptions) GraphiteRenderFetchOptionsBuilder() handleroptions.FetchOptionsBuilder {
   621  	return o.graphiteRenderFetchOptionsBuilder
   622  }
   623  
   624  func (o *handlerOptions) SetGraphiteRenderFetchOptionsBuilder(value handleroptions.FetchOptionsBuilder) HandlerOptions {
   625  	opts := *o
   626  	opts.graphiteRenderFetchOptionsBuilder = value
   627  	return &opts
   628  }
   629  
   630  func (o *handlerOptions) GraphiteRenderRouter() GraphiteRenderRouter {
   631  	return o.graphiteRenderRouter
   632  }
   633  
   634  func (o *handlerOptions) SetGraphiteRenderRouter(value GraphiteRenderRouter) HandlerOptions {
   635  	opts := *o
   636  	opts.graphiteRenderRouter = value
   637  	return &opts
   638  }
   639  
   640  func (o *handlerOptions) GraphiteFindRouter() GraphiteFindRouter {
   641  	return o.graphiteFindRouter
   642  }
   643  
   644  func (o *handlerOptions) SetGraphiteFindRouter(value GraphiteFindRouter) HandlerOptions {
   645  	opts := *o
   646  	opts.graphiteFindRouter = value
   647  	return &opts
   648  }
   649  
   650  func (o *handlerOptions) SetM3DBOptions(value m3.Options) HandlerOptions {
   651  	opts := *o
   652  	opts.m3dbOpts = value
   653  	return &opts
   654  }
   655  
   656  func (o *handlerOptions) M3DBOptions() m3.Options {
   657  	return o.m3dbOpts
   658  }
   659  
   660  func (o *handlerOptions) SetStoreMetricsType(value bool) HandlerOptions {
   661  	opts := *o
   662  	opts.storeMetricsType = value
   663  	return &opts
   664  }
   665  
   666  func (o *handlerOptions) StoreMetricsType() bool {
   667  	return o.storeMetricsType
   668  }
   669  
   670  func (o *handlerOptions) SetNamespaceValidator(value NamespaceValidator) HandlerOptions {
   671  	opts := *o
   672  	opts.namespaceValidator = value
   673  	return &opts
   674  }
   675  
   676  func (o *handlerOptions) NamespaceValidator() NamespaceValidator {
   677  	return o.namespaceValidator
   678  }
   679  
   680  // NamespaceValidator defines namespace validation logics.
   681  type NamespaceValidator interface {
   682  	// ValidateNewNamespace gets invoked when creating a new namespace.
   683  	ValidateNewNamespace(newNs dbnamespace.Metadata, existing []dbnamespace.Metadata) error
   684  }
   685  
   686  func (o *handlerOptions) SetKVStoreProtoParser(value KVStoreProtoParser) HandlerOptions {
   687  	opts := *o
   688  	opts.kvStoreProtoParser = value
   689  	return &opts
   690  }
   691  
   692  func (o *handlerOptions) KVStoreProtoParser() KVStoreProtoParser {
   693  	return o.kvStoreProtoParser
   694  }
   695  
   696  func (o *handlerOptions) RegisterMiddleware() middleware.Register {
   697  	return o.registerMiddleware
   698  }
   699  
   700  func (o *handlerOptions) SetRegisterMiddleware(value middleware.Register) HandlerOptions {
   701  	opts := *o
   702  	opts.registerMiddleware = value
   703  	return &opts
   704  }
   705  
   706  func (o *handlerOptions) DefaultLookback() time.Duration {
   707  	return o.defaultLookback
   708  }
   709  
   710  func (o *handlerOptions) SetDefaultLookback(value time.Duration) HandlerOptions {
   711  	opts := *o
   712  	opts.defaultLookback = value
   713  	return &opts
   714  }
   715  
   716  // KVStoreProtoParser parses protobuf messages based off specific keys.
   717  type KVStoreProtoParser func(key string) (protoiface.MessageV1, error)