Skip to content

Commit 0570e8b

Browse files
soundvibearnikolalinasmrobskillingtonwesleyk
authored
[query] Query handlers refactoring (#2872)
* Initial commit for proposed query handlers refactoring: * updated CustomHandler interface * unified how query routes are added. no need to pass router around and wrapping is done in one place. * routes are registered with names so they could be easily found later when custom handlers are registered. * trying to make linter happy * linter fixes * revert old behaviour * Make sure route methods are taken into account when adding and searching for named route. * fixed code formatting * [dbnode] Refactor wide query path (#2826) * [dbnode] Introduce Aggregator type (#2840) * [coordinator] Set default namespace tag to avoid colliding with commonly used "namespace" label (#2878) * [coordinator] Set default namespace tag to avoid colliding with common "namespace" default value * Use defined constant * Add downsampler test case to demonstrate override namespace tag Co-authored-by: Wesley Kim <[email protected]> * Improve some slow tests (#2881) * Improe some slow tests * lint * lint * goddamn imports * Changes after code review. * [query] Remove dead code in prom package (#2871) * Register separate route for each method. * linter fixes * removed code duplication in hasndler_test * Fail if route was already registered. * formatted code * Update src/query/api/v1/httpd/handler_test.go Co-authored-by: Vilius Pranckaitis <[email protected]> * Update src/query/api/v1/httpd/handler_test.go Co-authored-by: Vilius Pranckaitis <[email protected]> * More handler tests. Co-authored-by: arnikola <[email protected]> Co-authored-by: Linas Medžiūnas <[email protected]> Co-authored-by: Rob Skillington <[email protected]> Co-authored-by: Wesley Kim <[email protected]> Co-authored-by: Vytenis Darulis <[email protected]> Co-authored-by: Vilius Pranckaitis <[email protected]>
1 parent 45382dc commit 0570e8b

File tree

9 files changed

+468
-209
lines changed

9 files changed

+468
-209
lines changed

src/query/api/v1/handler/database/common.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,12 @@
2121
package database
2222

2323
import (
24-
"net/http"
25-
2624
clusterclient "github.com/m3db/m3/src/cluster/client"
2725
dbconfig "github.com/m3db/m3/src/cmd/services/m3dbnode/config"
2826
"github.com/m3db/m3/src/cmd/services/m3query/config"
27+
"github.com/m3db/m3/src/query/api/v1/handler"
2928
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
30-
"github.com/m3db/m3/src/query/util/logging"
3129
"github.com/m3db/m3/src/x/instrument"
32-
33-
"github.com/gorilla/mux"
3430
)
3531

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

4440
// RegisterRoutes registers the namespace routes
4541
func RegisterRoutes(
46-
r *mux.Router,
42+
addRoute handler.AddRouteFn,
4743
client clusterclient.Client,
4844
cfg config.Configuration,
4945
embeddedDbCfg *dbconfig.DBConfiguration,
5046
defaults []handleroptions.ServiceOptionsDefault,
5147
instrumentOpts instrument.Options,
5248
) error {
53-
wrapped := func(n http.Handler) http.Handler {
54-
return logging.WithResponseTimeAndPanicErrorLogging(n, instrumentOpts)
55-
}
56-
5749
createHandler, err := NewCreateHandler(client, cfg, embeddedDbCfg,
5850
defaults, instrumentOpts)
5951
if err != nil {
6052
return err
6153
}
6254

63-
r.HandleFunc(CreateURL,
64-
wrapped(createHandler).ServeHTTP).
65-
Methods(CreateHTTPMethod)
66-
6755
// Register the same handler under two different endpoints. This just makes explaining things in
6856
// our documentation easier so we can separate out concepts, but share the underlying code.
69-
r.HandleFunc(CreateURL, wrapped(createHandler).ServeHTTP).Methods(CreateHTTPMethod)
70-
r.HandleFunc(CreateNamespaceURL, wrapped(createHandler).ServeHTTP).Methods(CreateNamespaceHTTPMethod)
57+
if err := addRoute(CreateURL, createHandler, CreateHTTPMethod); err != nil {
58+
return err
59+
}
60+
if err := addRoute(CreateNamespaceURL, createHandler, CreateNamespaceHTTPMethod); err != nil {
61+
return err
62+
}
7163

7264
return nil
7365
}

src/query/api/v1/handler/namespace/common.go

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@ import (
3131
"github.com/m3db/m3/src/cluster/kv"
3232
nsproto "github.com/m3db/m3/src/dbnode/generated/proto/namespace"
3333
"github.com/m3db/m3/src/dbnode/namespace"
34+
"github.com/m3db/m3/src/query/api/v1/handler"
3435
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
3536
"github.com/m3db/m3/src/query/storage/m3"
36-
"github.com/m3db/m3/src/query/util/logging"
3737
"github.com/m3db/m3/src/x/instrument"
3838
xhttp "github.com/m3db/m3/src/x/net/http"
39-
40-
"github.com/gorilla/mux"
4139
)
4240

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

103+
type applyMiddlewareFn func(
104+
svc handleroptions.ServiceNameAndDefaults,
105+
w http.ResponseWriter,
106+
r *http.Request,
107+
)
108+
109+
type addRouteFn func(
110+
path string,
111+
applyMiddlewareFn applyMiddlewareFn,
112+
methods ...string,
113+
) error
114+
105115
// RegisterRoutes registers the namespace routes.
106116
func RegisterRoutes(
107-
r *mux.Router,
117+
addRouteFn handler.AddRouteFn,
108118
client clusterclient.Client,
109119
clusters m3.Clusters,
110120
defaults []handleroptions.ServiceOptionsDefault,
111121
instrumentOpts instrument.Options,
112-
) {
113-
wrapped := func(n http.Handler) http.Handler {
114-
return logging.WithResponseTimeAndPanicErrorLogging(n, instrumentOpts)
115-
}
116-
applyMiddleware := func(
117-
f func(svc handleroptions.ServiceNameAndDefaults,
118-
w http.ResponseWriter, r *http.Request),
119-
defaults []handleroptions.ServiceOptionsDefault,
120-
) http.Handler {
121-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
122-
svc := handleroptions.ServiceNameAndDefaults{
123-
ServiceName: handleroptions.M3DBServiceName,
124-
Defaults: defaults,
125-
}
126-
f(svc, w, r)
127-
})
128-
}
122+
) error {
123+
addRoute := applyMiddlewareToRoute(addRouteFn, defaults)
129124

130125
// Get M3DB namespaces.
131-
getHandler := wrapped(
132-
applyMiddleware(NewGetHandler(client, instrumentOpts).ServeHTTP, defaults))
133-
r.HandleFunc(M3DBGetURL, getHandler.ServeHTTP).Methods(GetHTTPMethod)
126+
getHandler := NewGetHandler(client, instrumentOpts).ServeHTTP
127+
if err := addRoute(M3DBGetURL, getHandler, GetHTTPMethod); err != nil {
128+
return err
129+
}
134130

135131
// Add M3DB namespaces.
136-
addHandler := wrapped(
137-
applyMiddleware(NewAddHandler(client, instrumentOpts).ServeHTTP, defaults))
138-
r.HandleFunc(M3DBAddURL, addHandler.ServeHTTP).Methods(AddHTTPMethod)
132+
addHandler := NewAddHandler(client, instrumentOpts).ServeHTTP
133+
if err := addRoute(M3DBAddURL, addHandler, AddHTTPMethod); err != nil {
134+
return err
135+
}
139136

140137
// Update M3DB namespaces.
141-
updateHandler := wrapped(
142-
applyMiddleware(NewUpdateHandler(client, instrumentOpts).ServeHTTP, defaults))
143-
r.HandleFunc(M3DBUpdateURL, updateHandler.ServeHTTP).Methods(UpdateHTTPMethod)
138+
updateHandler := NewUpdateHandler(client, instrumentOpts).ServeHTTP
139+
if err := addRoute(M3DBUpdateURL, updateHandler, UpdateHTTPMethod); err != nil {
140+
return err
141+
}
144142

145143
// Delete M3DB namespaces.
146-
deleteHandler := wrapped(
147-
applyMiddleware(NewDeleteHandler(client, instrumentOpts).ServeHTTP, defaults))
148-
r.HandleFunc(M3DBDeleteURL, deleteHandler.ServeHTTP).Methods(DeleteHTTPMethod)
144+
deleteHandler := NewDeleteHandler(client, instrumentOpts).ServeHTTP
145+
if err := addRoute(M3DBDeleteURL, deleteHandler, DeleteHTTPMethod); err != nil {
146+
return err
147+
}
149148

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

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

160161
// Mark M3DB namespace as ready.
161-
readyHandler := wrapped(
162-
applyMiddleware(NewReadyHandler(client, clusters, instrumentOpts).ServeHTTP, defaults))
163-
r.HandleFunc(M3DBReadyURL, readyHandler.ServeHTTP).Methods(ReadyHTTPMethod)
162+
readyHandler := NewReadyHandler(client, clusters, instrumentOpts).ServeHTTP
163+
if err := addRoute(M3DBReadyURL, readyHandler, ReadyHTTPMethod); err != nil {
164+
return err
165+
}
166+
167+
return nil
168+
}
164169

170+
func applyMiddlewareToRoute(
171+
addRouteFn handler.AddRouteFn,
172+
defaults []handleroptions.ServiceOptionsDefault,
173+
) addRouteFn {
174+
applyMiddleware := func(
175+
applyMiddlewareFn applyMiddlewareFn,
176+
defaults []handleroptions.ServiceOptionsDefault,
177+
) http.Handler {
178+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
179+
svc := handleroptions.ServiceNameAndDefaults{
180+
ServiceName: handleroptions.M3DBServiceName,
181+
Defaults: defaults,
182+
}
183+
applyMiddlewareFn(svc, w, r)
184+
})
185+
}
186+
187+
return func(path string, f applyMiddlewareFn, methods ...string) error {
188+
return addRouteFn(path, applyMiddleware(f, defaults), methods...)
189+
}
165190
}
166191

167192
func validateNamespaceAggregationOptions(mds []namespace.Metadata) error {

src/query/api/v1/handler/placement/common.go

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,12 @@ import (
3737
"github.com/m3db/m3/src/cluster/services"
3838
"github.com/m3db/m3/src/cluster/shard"
3939
"github.com/m3db/m3/src/cmd/services/m3query/config"
40+
"github.com/m3db/m3/src/query/api/v1/handler"
4041
"github.com/m3db/m3/src/query/api/v1/handler/prometheus/handleroptions"
4142
"github.com/m3db/m3/src/query/util/logging"
4243
xerrors "github.com/m3db/m3/src/x/errors"
4344
"github.com/m3db/m3/src/x/instrument"
4445
xhttp "github.com/m3db/m3/src/x/net/http"
45-
46-
"github.com/gorilla/mux"
4746
)
4847

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

223222
// RegisterRoutes registers the placement routes
224223
func RegisterRoutes(
225-
r *mux.Router,
224+
addRoute handler.AddRouteFn,
226225
defaults []handleroptions.ServiceOptionsDefault,
227226
opts HandlerOptions,
228-
) {
227+
) error {
229228
// Init
230229
var (
231230
initHandler = NewInitHandler(opts)
232231
initFn = applyMiddleware(initHandler.ServeHTTP, defaults, opts.instrumentOptions)
233232
)
234-
r.HandleFunc(M3DBInitURL, initFn).Methods(InitHTTPMethod)
235-
r.HandleFunc(M3AggInitURL, initFn).Methods(InitHTTPMethod)
236-
r.HandleFunc(M3CoordinatorInitURL, initFn).Methods(InitHTTPMethod)
233+
234+
if err := addRoute(M3DBInitURL, initFn, InitHTTPMethod); err != nil {
235+
return err
236+
}
237+
if err := addRoute(M3AggInitURL, initFn, InitHTTPMethod); err != nil {
238+
return err
239+
}
240+
if err := addRoute(M3CoordinatorInitURL, initFn, InitHTTPMethod); err != nil {
241+
return err
242+
}
237243

238244
// Get
239245
var (
240246
getHandler = NewGetHandler(opts)
241247
getFn = applyMiddleware(getHandler.ServeHTTP, defaults, opts.instrumentOptions)
242248
)
243-
r.HandleFunc(M3DBGetURL, getFn).Methods(GetHTTPMethod)
244-
r.HandleFunc(M3AggGetURL, getFn).Methods(GetHTTPMethod)
245-
r.HandleFunc(M3CoordinatorGetURL, getFn).Methods(GetHTTPMethod)
249+
if err := addRoute(M3DBGetURL, getFn, GetHTTPMethod); err != nil {
250+
return err
251+
}
252+
if err := addRoute(M3AggGetURL, getFn, GetHTTPMethod); err != nil {
253+
return err
254+
}
255+
if err := addRoute(M3CoordinatorGetURL, getFn, GetHTTPMethod); err != nil {
256+
return err
257+
}
246258

247259
// Delete all
248260
var (
249261
deleteAllHandler = NewDeleteAllHandler(opts)
250262
deleteAllFn = applyMiddleware(deleteAllHandler.ServeHTTP, defaults, opts.instrumentOptions)
251263
)
252-
r.HandleFunc(M3DBDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
253-
r.HandleFunc(M3AggDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
254-
r.HandleFunc(M3CoordinatorDeleteAllURL, deleteAllFn).Methods(DeleteAllHTTPMethod)
264+
if err := addRoute(M3DBDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
265+
return err
266+
}
267+
if err := addRoute(M3AggDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
268+
return err
269+
}
270+
if err := addRoute(M3CoordinatorDeleteAllURL, deleteAllFn, DeleteAllHTTPMethod); err != nil {
271+
return err
272+
}
255273

256274
// Add
257275
var (
258276
addHandler = NewAddHandler(opts)
259277
addFn = applyMiddleware(addHandler.ServeHTTP, defaults, opts.instrumentOptions)
260278
)
261-
r.HandleFunc(M3DBAddURL, addFn).Methods(AddHTTPMethod)
262-
r.HandleFunc(M3AggAddURL, addFn).Methods(AddHTTPMethod)
263-
r.HandleFunc(M3CoordinatorAddURL, addFn).Methods(AddHTTPMethod)
279+
if err := addRoute(M3DBAddURL, addFn, AddHTTPMethod); err != nil {
280+
return err
281+
}
282+
if err := addRoute(M3AggAddURL, addFn, AddHTTPMethod); err != nil {
283+
return err
284+
}
285+
if err := addRoute(M3CoordinatorAddURL, addFn, AddHTTPMethod); err != nil {
286+
return err
287+
}
264288

265289
// Delete
266290
var (
267291
deleteHandler = NewDeleteHandler(opts)
268292
deleteFn = applyMiddleware(deleteHandler.ServeHTTP, defaults, opts.instrumentOptions)
269293
)
270-
r.HandleFunc(M3DBDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
271-
r.HandleFunc(M3AggDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
272-
r.HandleFunc(M3CoordinatorDeleteURL, deleteFn).Methods(DeleteHTTPMethod)
294+
if err := addRoute(M3DBDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
295+
return err
296+
}
297+
if err := addRoute(M3AggDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
298+
return err
299+
}
300+
if err := addRoute(M3CoordinatorDeleteURL, deleteFn, DeleteHTTPMethod); err != nil {
301+
return err
302+
}
273303

274304
// Replace
275305
var (
276306
replaceHandler = NewReplaceHandler(opts)
277307
replaceFn = applyMiddleware(replaceHandler.ServeHTTP, defaults, opts.instrumentOptions)
278308
)
279-
r.HandleFunc(M3DBReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
280-
r.HandleFunc(M3AggReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
281-
r.HandleFunc(M3CoordinatorReplaceURL, replaceFn).Methods(ReplaceHTTPMethod)
309+
if err := addRoute(M3DBReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
310+
return err
311+
}
312+
if err := addRoute(M3AggReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
313+
return err
314+
}
315+
if err := addRoute(M3CoordinatorReplaceURL, replaceFn, ReplaceHTTPMethod); err != nil {
316+
return err
317+
}
282318

283319
// Set
284320
var (
285321
setHandler = NewSetHandler(opts)
286322
setFn = applyMiddleware(setHandler.ServeHTTP, defaults, opts.instrumentOptions)
287323
)
288-
r.HandleFunc(M3DBSetURL, setFn).Methods(SetHTTPMethod)
289-
r.HandleFunc(M3AggSetURL, setFn).Methods(SetHTTPMethod)
290-
r.HandleFunc(M3CoordinatorSetURL, setFn).Methods(SetHTTPMethod)
324+
if err := addRoute(M3DBSetURL, setFn, SetHTTPMethod); err != nil {
325+
return err
326+
}
327+
if err := addRoute(M3AggSetURL, setFn, SetHTTPMethod); err != nil {
328+
return err
329+
}
330+
if err := addRoute(M3CoordinatorSetURL, setFn, SetHTTPMethod); err != nil {
331+
return err
332+
}
333+
334+
return nil
291335
}
292336

293337
func newPlacementCutoverNanosFn(
@@ -386,11 +430,11 @@ func applyMiddleware(
386430
f func(svc handleroptions.ServiceNameAndDefaults, w http.ResponseWriter, r *http.Request),
387431
defaults []handleroptions.ServiceOptionsDefault,
388432
instrumentOpts instrument.Options,
389-
) func(w http.ResponseWriter, r *http.Request) {
433+
) http.Handler {
390434
return logging.WithResponseTimeAndPanicErrorLoggingFunc(
391435
parseServiceMiddleware(f, defaults),
392436
instrumentOpts,
393-
).ServeHTTP
437+
)
394438
}
395439

396440
func parseServiceMiddleware(

0 commit comments

Comments
 (0)