Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[query] Query handlers refactoring #2872

Merged
merged 24 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
69e69d5
Initial commit for proposed query handlers refactoring:
soundvibe Nov 11, 2020
1fe3aa1
Merge branch 'master' into linasn/query-handlers-refactoring
soundvibe Nov 11, 2020
5ebcdeb
trying to make linter happy
soundvibe Nov 11, 2020
67814a7
linter fixes
soundvibe Nov 11, 2020
eaddb85
revert old behaviour
soundvibe Nov 11, 2020
3b04c30
Make sure route methods are taken into account when adding and search…
soundvibe Nov 11, 2020
ea121f2
fixed code formatting
soundvibe Nov 11, 2020
dd38ead
[dbnode] Refactor wide query path (#2826)
arnikola Nov 11, 2020
a3bd18a
[dbnode] Introduce Aggregator type (#2840)
linasm Nov 11, 2020
3b5c0ff
[coordinator] Set default namespace tag to avoid colliding with commo…
robskillington Nov 12, 2020
96a5efb
Improve some slow tests (#2881)
vdarulis Nov 12, 2020
9b9c6da
Changes after code review.
soundvibe Nov 12, 2020
78db238
[query] Remove dead code in prom package (#2871)
vpranckaitis Nov 12, 2020
9af0b72
Register separate route for each method.
soundvibe Nov 12, 2020
5814642
linter fixes
soundvibe Nov 12, 2020
a7d6696
removed code duplication in hasndler_test
soundvibe Nov 12, 2020
03f5e35
Merge branch 'master' into linasn/query-handlers-refactoring
soundvibe Nov 12, 2020
3a3a885
Fail if route was already registered.
soundvibe Nov 12, 2020
2d71d9a
formatted code
soundvibe Nov 12, 2020
6b82ce4
Merge branch 'master' into linasn/query-handlers-refactoring
soundvibe Nov 16, 2020
c46d9fd
Update src/query/api/v1/httpd/handler_test.go
soundvibe Nov 16, 2020
ff3a894
Update src/query/api/v1/httpd/handler_test.go
soundvibe Nov 16, 2020
3bc8e4c
More handler tests.
soundvibe Nov 16, 2020
b956426
Merge branch 'master' into linasn/query-handlers-refactoring
soundvibe Nov 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions src/query/api/v1/handler/database/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@
package database

import (
"net/http"

clusterclient "github.com/m3db/m3/src/cluster/client"
dbconfig "github.com/m3db/m3/src/cmd/services/m3dbnode/config"
"github.com/m3db/m3/src/cmd/services/m3query/config"
"github.com/m3db/m3/src/query/api/v1/handler"
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
"github.com/m3db/m3/src/query/util/logging"
"github.com/m3db/m3/src/x/instrument"

"github.com/gorilla/mux"
)

// Handler represents a generic handler for namespace endpoints.
Expand All @@ -43,31 +39,27 @@ type Handler struct {

// RegisterRoutes registers the namespace routes
func RegisterRoutes(
r *mux.Router,
addRoute handler.AddRouteFn,
client clusterclient.Client,
cfg config.Configuration,
embeddedDbCfg *dbconfig.DBConfiguration,
defaults []handleroptions.ServiceOptionsDefault,
instrumentOpts instrument.Options,
) error {
wrapped := func(n http.Handler) http.Handler {
return logging.WithResponseTimeAndPanicErrorLogging(n, instrumentOpts)
}

createHandler, err := NewCreateHandler(client, cfg, embeddedDbCfg,
defaults, instrumentOpts)
if err != nil {
return err
}

r.HandleFunc(CreateURL,
wrapped(createHandler).ServeHTTP).
Methods(CreateHTTPMethod)

// Register the same handler under two different endpoints. This just makes explaining things in
// our documentation easier so we can separate out concepts, but share the underlying code.
r.HandleFunc(CreateURL, wrapped(createHandler).ServeHTTP).Methods(CreateHTTPMethod)
r.HandleFunc(CreateNamespaceURL, wrapped(createHandler).ServeHTTP).Methods(CreateNamespaceHTTPMethod)
if err := addRoute(CreateURL, createHandler, CreateHTTPMethod); err != nil {
return err
}
if err := addRoute(CreateNamespaceURL, createHandler, CreateNamespaceHTTPMethod); err != nil {
return err
}

return nil
}
109 changes: 67 additions & 42 deletions src/query/api/v1/handler/namespace/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ import (
"github.com/m3db/m3/src/cluster/kv"
nsproto "github.com/m3db/m3/src/dbnode/generated/proto/namespace"
"github.com/m3db/m3/src/dbnode/namespace"
"github.com/m3db/m3/src/query/api/v1/handler"
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
"github.com/m3db/m3/src/query/storage/m3"
"github.com/m3db/m3/src/query/util/logging"
"github.com/m3db/m3/src/x/instrument"
xhttp "github.com/m3db/m3/src/x/net/http"

"github.com/gorilla/mux"
)

const (
Expand Down Expand Up @@ -102,66 +100,93 @@ func Metadata(store kv.Store) ([]namespace.Metadata, int, error) {
return nsMap.Metadatas(), value.Version(), nil
}

type applyMiddlewareFn func(
svc handleroptions.ServiceNameAndDefaults,
w http.ResponseWriter,
r *http.Request,
)

type addRouteFn func(
path string,
applyMiddlewareFn applyMiddlewareFn,
methods ...string,
) error

// RegisterRoutes registers the namespace routes.
func RegisterRoutes(
r *mux.Router,
addRouteFn handler.AddRouteFn,
client clusterclient.Client,
clusters m3.Clusters,
defaults []handleroptions.ServiceOptionsDefault,
instrumentOpts instrument.Options,
) {
wrapped := func(n http.Handler) http.Handler {
return logging.WithResponseTimeAndPanicErrorLogging(n, instrumentOpts)
}
applyMiddleware := func(
f func(svc handleroptions.ServiceNameAndDefaults,
w http.ResponseWriter, r *http.Request),
defaults []handleroptions.ServiceOptionsDefault,
) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
svc := handleroptions.ServiceNameAndDefaults{
ServiceName: handleroptions.M3DBServiceName,
Defaults: defaults,
}
f(svc, w, r)
})
}
) error {
addRoute := applyMiddlewareToRoute(addRouteFn, defaults)

// Get M3DB namespaces.
getHandler := wrapped(
applyMiddleware(NewGetHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBGetURL, getHandler.ServeHTTP).Methods(GetHTTPMethod)
getHandler := NewGetHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBGetURL, getHandler, GetHTTPMethod); err != nil {
return err
}

// Add M3DB namespaces.
addHandler := wrapped(
applyMiddleware(NewAddHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBAddURL, addHandler.ServeHTTP).Methods(AddHTTPMethod)
addHandler := NewAddHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBAddURL, addHandler, AddHTTPMethod); err != nil {
return err
}

// Update M3DB namespaces.
updateHandler := wrapped(
applyMiddleware(NewUpdateHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBUpdateURL, updateHandler.ServeHTTP).Methods(UpdateHTTPMethod)
updateHandler := NewUpdateHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBUpdateURL, updateHandler, UpdateHTTPMethod); err != nil {
return err
}

// Delete M3DB namespaces.
deleteHandler := wrapped(
applyMiddleware(NewDeleteHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBDeleteURL, deleteHandler.ServeHTTP).Methods(DeleteHTTPMethod)
deleteHandler := NewDeleteHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBDeleteURL, deleteHandler, DeleteHTTPMethod); err != nil {
return err
}

// Deploy M3DB schemas.
schemaHandler := wrapped(
applyMiddleware(NewSchemaHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBSchemaURL, schemaHandler.ServeHTTP).Methods(SchemaDeployHTTPMethod)
schemaHandler := NewSchemaHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBSchemaURL, schemaHandler, SchemaDeployHTTPMethod); err != nil {
return err
}

// Reset M3DB schemas.
schemaResetHandler := wrapped(
applyMiddleware(NewSchemaResetHandler(client, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBSchemaURL, schemaResetHandler.ServeHTTP).Methods(DeleteHTTPMethod)
schemaResetHandler := NewSchemaResetHandler(client, instrumentOpts).ServeHTTP
if err := addRoute(M3DBSchemaURL, schemaResetHandler, DeleteHTTPMethod); err != nil {
return err
}

// Mark M3DB namespace as ready.
readyHandler := wrapped(
applyMiddleware(NewReadyHandler(client, clusters, instrumentOpts).ServeHTTP, defaults))
r.HandleFunc(M3DBReadyURL, readyHandler.ServeHTTP).Methods(ReadyHTTPMethod)
readyHandler := NewReadyHandler(client, clusters, instrumentOpts).ServeHTTP
if err := addRoute(M3DBReadyURL, readyHandler, ReadyHTTPMethod); err != nil {
return err
}

return nil
}

func applyMiddlewareToRoute(
addRouteFn handler.AddRouteFn,
defaults []handleroptions.ServiceOptionsDefault,
) addRouteFn {
applyMiddleware := func(
applyMiddlewareFn applyMiddlewareFn,
defaults []handleroptions.ServiceOptionsDefault,
) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
svc := handleroptions.ServiceNameAndDefaults{
ServiceName: handleroptions.M3DBServiceName,
Defaults: defaults,
}
applyMiddlewareFn(svc, w, r)
})
}

return func(path string, f applyMiddlewareFn, methods ...string) error {
return addRouteFn(path, applyMiddleware(f, defaults), methods...)
}
}

func validateNamespaceAggregationOptions(mds []namespace.Metadata) error {
Expand Down
98 changes: 71 additions & 27 deletions src/query/api/v1/handler/placement/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ import (
"github.com/m3db/m3/src/cluster/services"
"github.com/m3db/m3/src/cluster/shard"
"github.com/m3db/m3/src/cmd/services/m3query/config"
"github.com/m3db/m3/src/query/api/v1/handler"
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
"github.com/m3db/m3/src/query/util/logging"
xerrors "github.com/m3db/m3/src/x/errors"
"github.com/m3db/m3/src/x/instrument"
xhttp "github.com/m3db/m3/src/x/net/http"

"github.com/gorilla/mux"
)

const (
Expand Down Expand Up @@ -222,72 +221,117 @@ func ConvertInstancesProto(instancesProto []*placementpb.Instance) ([]placement.

// RegisterRoutes registers the placement routes
func RegisterRoutes(
r *mux.Router,
addRoute handler.AddRouteFn,
defaults []handleroptions.ServiceOptionsDefault,
opts HandlerOptions,
) {
) error {
// Init
var (
initHandler = NewInitHandler(opts)
initFn = applyMiddleware(initHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBInitURL, initFn).Methods(InitHTTPMethod)
r.HandleFunc(M3AggInitURL, initFn).Methods(InitHTTPMethod)
r.HandleFunc(M3CoordinatorInitURL, initFn).Methods(InitHTTPMethod)

if err := addRoute(M3DBInitURL, initFn, InitHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggInitURL, initFn, InitHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorInitURL, initFn, InitHTTPMethod); err != nil {
return err
}

// Get
var (
getHandler = NewGetHandler(opts)
getFn = applyMiddleware(getHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBGetURL, getFn).Methods(GetHTTPMethod)
r.HandleFunc(M3AggGetURL, getFn).Methods(GetHTTPMethod)
r.HandleFunc(M3CoordinatorGetURL, getFn).Methods(GetHTTPMethod)
if err := addRoute(M3DBGetURL, getFn, GetHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggGetURL, getFn, GetHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorGetURL, getFn, GetHTTPMethod); err != nil {
return err
}

// Delete all
var (
deleteAllHandler = NewDeleteAllHandler(opts)
deleteAllFn = applyMiddleware(deleteAllHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
r.HandleFunc(M3AggDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
r.HandleFunc(M3CoordinatorDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
if err := addRoute(M3DBDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
return err
}

// Add
var (
addHandler = NewAddHandler(opts)
addFn = applyMiddleware(addHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBAddURL, addFn).Methods(AddHTTPMethod)
r.HandleFunc(M3AggAddURL, addFn).Methods(AddHTTPMethod)
r.HandleFunc(M3CoordinatorAddURL, addFn).Methods(AddHTTPMethod)
if err := addRoute(M3DBAddURL, addFn, AddHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggAddURL, addFn, AddHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorAddURL, addFn, AddHTTPMethod); err != nil {
return err
}

// Delete
var (
deleteHandler = NewDeleteHandler(opts)
deleteFn = applyMiddleware(deleteHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
r.HandleFunc(M3AggDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
r.HandleFunc(M3CoordinatorDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
if err := addRoute(M3DBDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
return err
}

// Replace
var (
replaceHandler = NewReplaceHandler(opts)
replaceFn = applyMiddleware(replaceHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
r.HandleFunc(M3AggReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
r.HandleFunc(M3CoordinatorReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
if err := addRoute(M3DBReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
return err
}

// Set
var (
setHandler = NewSetHandler(opts)
setFn = applyMiddleware(setHandler.ServeHTTP, defaults, opts.instrumentOptions)
)
r.HandleFunc(M3DBSetURL, setFn).Methods(SetHTTPMethod)
r.HandleFunc(M3AggSetURL, setFn).Methods(SetHTTPMethod)
r.HandleFunc(M3CoordinatorSetURL, setFn).Methods(SetHTTPMethod)
if err := addRoute(M3DBSetURL, setFn, SetHTTPMethod); err != nil {
return err
}
if err := addRoute(M3AggSetURL, setFn, SetHTTPMethod); err != nil {
return err
}
if err := addRoute(M3CoordinatorSetURL, setFn, SetHTTPMethod); err != nil {
return err
}

return nil
}

func newPlacementCutoverNanosFn(
Expand Down Expand Up @@ -386,11 +430,11 @@ func applyMiddleware(
f func(svc handleroptions.ServiceNameAndDefaults, w http.ResponseWriter, r *http.Request),
defaults []handleroptions.ServiceOptionsDefault,
instrumentOpts instrument.Options,
) func(w http.ResponseWriter, r *http.Request) {
) http.Handler {
return logging.WithResponseTimeAndPanicErrorLoggingFunc(
parseServiceMiddleware(f, defaults),
instrumentOpts,
).ServeHTTP
)
}

func parseServiceMiddleware(
Expand Down
Loading