浏览代码

introduce concept of named middleware

bergquist 8 年之前
父节点
当前提交
9c30bf53cf
共有 3 个文件被更改,包括 122 次插入16 次删除
  1. 1 1
      pkg/api/api.go
  2. 23 14
      pkg/api/route_register.go
  3. 98 1
      pkg/api/route_register_test.go

+ 1 - 1
pkg/api/api.go

@@ -21,7 +21,7 @@ func (hs *HttpServer) registerRoutes() {
 	// automatically set HEAD for every GET
 	macaronR.SetAutoHead(true)
 
-	r := newRouteRegister()
+	r := newRouteRegister(middleware.RequestMetrics)
 
 	// not logged in views
 	r.Get("/", reqSignedIn, Index)

+ 23 - 14
pkg/api/route_register.go

@@ -3,7 +3,6 @@ package api
 import (
 	"net/http"
 
-	"github.com/grafana/grafana/pkg/middleware"
 	macaron "gopkg.in/macaron.v1"
 )
 
@@ -24,11 +23,14 @@ type RouteRegister interface {
 	Register(Router) *macaron.Router
 }
 
-func newRouteRegister() RouteRegister {
+type RegisterNamedMiddleware func(name string) macaron.Handler
+
+func newRouteRegister(namedMiddleware ...RegisterNamedMiddleware) RouteRegister {
 	return &routeRegister{
-		prefix:         "",
-		routes:         []route{},
-		subfixHandlers: []macaron.Handler{},
+		prefix:          "",
+		routes:          []route{},
+		subfixHandlers:  []macaron.Handler{},
+		namedMiddleware: namedMiddleware,
 	}
 }
 
@@ -39,17 +41,19 @@ type route struct {
 }
 
 type routeRegister struct {
-	prefix         string
-	subfixHandlers []macaron.Handler
-	routes         []route
-	groups         []*routeRegister
+	prefix          string
+	subfixHandlers  []macaron.Handler
+	namedMiddleware []RegisterNamedMiddleware
+	routes          []route
+	groups          []*routeRegister
 }
 
 func (rr *routeRegister) Group(pattern string, fn func(rr RouteRegister), handlers ...macaron.Handler) {
 	group := &routeRegister{
-		prefix:         rr.prefix + pattern,
-		subfixHandlers: append(rr.subfixHandlers, handlers...),
-		routes:         []route{},
+		prefix:          rr.prefix + pattern,
+		subfixHandlers:  append(rr.subfixHandlers, handlers...),
+		routes:          []route{},
+		namedMiddleware: rr.namedMiddleware,
 	}
 
 	fn(group)
@@ -71,8 +75,13 @@ func (rr *routeRegister) Register(router Router) *macaron.Router {
 func (rr *routeRegister) route(pattern, method string, handlers ...macaron.Handler) {
 	//inject tracing
 
-	h := append(rr.subfixHandlers, handlers...)
-	h = append([]macaron.Handler{middleware.RequestMetrics(pattern)}, h...)
+	h := make([]macaron.Handler, 0)
+	for _, fn := range rr.namedMiddleware {
+		h = append(h, fn(pattern))
+	}
+
+	h = append(h, rr.subfixHandlers...)
+	h = append(h, handlers...)
 
 	rr.routes = append(rr.routes, route{
 		method:   method,

+ 98 - 1
pkg/api/route_register_test.go

@@ -33,7 +33,48 @@ func emptyHandler(name string) macaron.Handler {
 	return struct{ name string }{name: name}
 }
 
-func TestRouteRegister(t *testing.T) {
+func TestRouteSimpleRegister(t *testing.T) {
+	testTable := []route{
+		{method: "DELETE", pattern: "/admin", handlers: emptyHandlers(2)},
+		{method: "GET", pattern: "/down", handlers: emptyHandlers(3)},
+	}
+
+	// Setup
+	rr := newRouteRegister(func(name string) macaron.Handler {
+		return emptyHandler(name)
+	})
+
+	rr.Delete("/admin", emptyHandler("1"))
+	rr.Get("/down", emptyHandler("1"), emptyHandler("2"))
+
+	fr := &fakeRouter{}
+	rr.Register(fr)
+
+	// Validation
+	if len(fr.route) != len(testTable) {
+		t.Errorf("want %v routes, got %v", len(testTable), len(fr.route))
+	}
+
+	for i, _ := range testTable {
+		if testTable[i].method != fr.route[i].method {
+			t.Errorf("want %s got %v", testTable[i].method, fr.route[i].method)
+		}
+
+		if testTable[i].pattern != fr.route[i].pattern {
+			t.Errorf("want %s got %v", testTable[i].pattern, fr.route[i].pattern)
+		}
+
+		if len(testTable[i].handlers) != len(fr.route[i].handlers) {
+			t.Errorf("want %d handlers got %d handlers \ntestcase: %v\nroute: %v\n",
+				len(testTable[i].handlers),
+				len(fr.route[i].handlers),
+				testTable[i],
+				fr.route[i])
+		}
+	}
+}
+
+func TestRouteGroupedRegister(t *testing.T) {
 	testTable := []route{
 		{method: "DELETE", pattern: "/admin", handlers: emptyHandlers(1)},
 		{method: "GET", pattern: "/down", handlers: emptyHandlers(2)},
@@ -86,3 +127,59 @@ func TestRouteRegister(t *testing.T) {
 		}
 	}
 }
+
+func TestNamedMiddlewareRouteRegister(t *testing.T) {
+	testTable := []route{
+		{method: "DELETE", pattern: "/admin", handlers: emptyHandlers(2)},
+		{method: "GET", pattern: "/down", handlers: emptyHandlers(3)},
+		{method: "POST", pattern: "/user", handlers: emptyHandlers(2)},
+		{method: "PUT", pattern: "/user/friends", handlers: emptyHandlers(2)},
+		{method: "DELETE", pattern: "/user/admin", handlers: emptyHandlers(3)},
+		{method: "GET", pattern: "/user/admin/all", handlers: emptyHandlers(5)},
+	}
+
+	// Setup
+	rr := newRouteRegister(func(name string) macaron.Handler {
+		return emptyHandler(name)
+	})
+
+	rr.Delete("/admin", emptyHandler("1"))
+	rr.Get("/down", emptyHandler("1"), emptyHandler("2"))
+
+	rr.Group("/user", func(user RouteRegister) {
+		user.Post("", emptyHandler("1"))
+		user.Put("/friends", emptyHandler("2"))
+
+		user.Group("/admin", func(admin RouteRegister) {
+			admin.Delete("", emptyHandler("3"))
+			admin.Get("/all", emptyHandler("3"), emptyHandler("4"), emptyHandler("5"))
+
+		}, emptyHandler("3"))
+	})
+
+	fr := &fakeRouter{}
+	rr.Register(fr)
+
+	// Validation
+	if len(fr.route) != len(testTable) {
+		t.Errorf("want %v routes, got %v", len(testTable), len(fr.route))
+	}
+
+	for i, _ := range testTable {
+		if testTable[i].method != fr.route[i].method {
+			t.Errorf("want %s got %v", testTable[i].method, fr.route[i].method)
+		}
+
+		if testTable[i].pattern != fr.route[i].pattern {
+			t.Errorf("want %s got %v", testTable[i].pattern, fr.route[i].pattern)
+		}
+
+		if len(testTable[i].handlers) != len(fr.route[i].handlers) {
+			t.Errorf("want %d handlers got %d handlers \ntestcase: %v\nroute: %v\n",
+				len(testTable[i].handlers),
+				len(fr.route[i].handlers),
+				testTable[i],
+				fr.route[i])
+		}
+	}
+}