From 4ff959ef50a6e2e2872de9a4fd85aff2d3a4a366 Mon Sep 17 00:00:00 2001 From: Ben Toogood Date: Thu, 9 Apr 2020 11:03:33 +0100 Subject: [PATCH] Dynamic Namespace --- api/handler/http/http_test.go | 2 +- api/resolver/options.go | 15 +++++++++++++-- api/resolver/path/path.go | 4 +++- api/resolver/resolver.go | 9 ++++++++- api/resolver/vpath/vpath.go | 10 ++++++---- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/api/handler/http/http_test.go b/api/handler/http/http_test.go index 6844a45a..f0ccd1ff 100644 --- a/api/handler/http/http_test.go +++ b/api/handler/http/http_test.go @@ -58,7 +58,7 @@ func testHttp(t *testing.T, path, service, ns string) { router.WithHandler("http"), router.WithRegistry(r), router.WithResolver(vpath.NewResolver( - resolver.WithNamespace(ns), + resolver.WithNamespace(resolver.StaticNamespace(ns)), )), ) diff --git a/api/resolver/options.go b/api/resolver/options.go index ce4b2e49..eb9ce875 100644 --- a/api/resolver/options.go +++ b/api/resolver/options.go @@ -1,11 +1,22 @@ package resolver +import ( + "net/http" + + "github.com/micro/go-micro/v2/auth" +) + // NewOptions returns new initialised options func NewOptions(opts ...Option) Options { var options Options for _, o := range opts { o(&options) } + + if options.Namespace == nil { + options.Namespace = StaticNamespace(auth.DefaultNamespace) + } + return options } @@ -16,8 +27,8 @@ func WithHandler(h string) Option { } } -// WithNamespace sets the namespace being used -func WithNamespace(n string) Option { +// WithNamespace sets the function which determines the namespace for a request +func WithNamespace(n func(*http.Request) string) Option { return func(o *Options) { o.Namespace = n } diff --git a/api/resolver/path/path.go b/api/resolver/path/path.go index 88bec8a7..84a92656 100644 --- a/api/resolver/path/path.go +++ b/api/resolver/path/path.go @@ -18,8 +18,10 @@ func (r *Resolver) Resolve(req *http.Request) (*resolver.Endpoint, error) { } parts := strings.Split(req.URL.Path[1:], "/") + ns := r.opts.Namespace(req) + return &resolver.Endpoint{ - Name: r.opts.Namespace + "." + parts[0], + Name: ns + "." + parts[0], Host: req.Host, Method: req.Method, Path: req.URL.Path, diff --git a/api/resolver/resolver.go b/api/resolver/resolver.go index 12854b19..81e8194d 100644 --- a/api/resolver/resolver.go +++ b/api/resolver/resolver.go @@ -31,7 +31,14 @@ type Endpoint struct { type Options struct { Handler string - Namespace string + Namespace func(*http.Request) string } type Option func(o *Options) + +// StaticNamespace returns the same namespace for each request +func StaticNamespace(ns string) func(*http.Request) string { + return func(*http.Request) string { + return ns + } +} diff --git a/api/resolver/vpath/vpath.go b/api/resolver/vpath/vpath.go index f1e49399..cf407ded 100644 --- a/api/resolver/vpath/vpath.go +++ b/api/resolver/vpath/vpath.go @@ -33,7 +33,7 @@ func (r *Resolver) Resolve(req *http.Request) (*resolver.Endpoint, error) { parts := strings.Split(req.URL.Path[1:], "/") if len(parts) == 1 { return &resolver.Endpoint{ - Name: addNamespace(r.opts.Namespace, parts...), + Name: r.withNamespace(req, parts...), Host: req.Host, Method: req.Method, Path: req.URL.Path, @@ -43,7 +43,7 @@ func (r *Resolver) Resolve(req *http.Request) (*resolver.Endpoint, error) { // /v1/foo if re.MatchString(parts[0]) { return &resolver.Endpoint{ - Name: addNamespace(r.opts.Namespace, parts[0:2]...), + Name: r.withNamespace(req, parts[0:2]...), Host: req.Host, Method: req.Method, Path: req.URL.Path, @@ -51,7 +51,7 @@ func (r *Resolver) Resolve(req *http.Request) (*resolver.Endpoint, error) { } return &resolver.Endpoint{ - Name: addNamespace(r.opts.Namespace, parts[0]), + Name: r.withNamespace(req, parts[0]), Host: req.Host, Method: req.Method, Path: req.URL.Path, @@ -62,9 +62,11 @@ func (r *Resolver) String() string { return "path" } -func addNamespace(ns string, parts ...string) string { +func (r *Resolver) withNamespace(req *http.Request, parts ...string) string { + ns := r.opts.Namespace(req) if len(ns) == 0 { return strings.Join(parts, ".") } + return strings.Join(append([]string{ns}, parts...), ".") }