This is an automated email from the ASF dual-hosted git repository.

asifdxtreme pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new ea31a1a  SCB-994 SC can not read the context when client using grpc 
api (#476)
ea31a1a is described below

commit ea31a1a3c9fdbd242817157f61e4aad15bfa5f0f
Author: little-cui <[email protected]>
AuthorDate: Sat Nov 3 00:19:28 2018 +0800

    SCB-994 SC can not read the context when client using grpc api (#476)
    
    * Support gRPC context
    
    * Bug fixes
---
 pkg/util/context.go                              | 30 ++++++++-----
 pkg/util/context_grpc.go                         | 32 +++++++++++++
 pkg/util/context_grpc_test.go                    | 57 ++++++++++++++++++++++++
 server/handler/context/v3.go                     |  4 +-
 server/handler/context/v4.go                     |  4 +-
 server/rest/controller/v4/instance_controller.go |  8 ++--
 server/service/instance.go                       |  2 +-
 7 files changed, 118 insertions(+), 19 deletions(-)

diff --git a/pkg/util/context.go b/pkg/util/context.go
index 79fb515..838d4a6 100644
--- a/pkg/util/context.go
+++ b/pkg/util/context.go
@@ -22,6 +22,13 @@ import (
        "time"
 )
 
+const (
+       CtxDomain        = "domain"
+       CtxProject       = "project"
+       CtxTargetDomain  = "target-domain"
+       CtxTargetProject = "target-project"
+)
+
 type StringContext struct {
        parentCtx context.Context
        kv        *ConcurrentMap
@@ -46,7 +53,7 @@ func (c *StringContext) Value(key interface{}) interface{} {
        }
        v, ok := c.kv.Get(k)
        if !ok {
-               return c.parentCtx.Value(key)
+               return FromContext(c.parentCtx, k)
        }
        return v
 }
@@ -94,7 +101,10 @@ func CloneContext(ctx context.Context) context.Context {
 }
 
 func FromContext(ctx context.Context, key string) interface{} {
-       return ctx.Value(key)
+       if v := ctx.Value(key); v != nil {
+               return v
+       }
+       return FromMetadata(ctx, key)
 }
 
 func SetRequestContext(r *http.Request, key string, val interface{}) 
*http.Request {
@@ -116,7 +126,7 @@ func ParseTargetDomainProject(ctx context.Context) string {
 }
 
 func ParseDomain(ctx context.Context) string {
-       v, ok := FromContext(ctx, "domain").(string)
+       v, ok := FromContext(ctx, CtxDomain).(string)
        if !ok {
                return ""
        }
@@ -124,7 +134,7 @@ func ParseDomain(ctx context.Context) string {
 }
 
 func ParseTargetDomain(ctx context.Context) string {
-       v, _ := FromContext(ctx, "target-domain").(string)
+       v, _ := FromContext(ctx, CtxTargetDomain).(string)
        if len(v) == 0 {
                return ParseDomain(ctx)
        }
@@ -132,7 +142,7 @@ func ParseTargetDomain(ctx context.Context) string {
 }
 
 func ParseProject(ctx context.Context) string {
-       v, ok := FromContext(ctx, "project").(string)
+       v, ok := FromContext(ctx, CtxProject).(string)
        if !ok {
                return ""
        }
@@ -140,7 +150,7 @@ func ParseProject(ctx context.Context) string {
 }
 
 func ParseTargetProject(ctx context.Context) string {
-       v, _ := FromContext(ctx, "target-project").(string)
+       v, _ := FromContext(ctx, CtxTargetProject).(string)
        if len(v) == 0 {
                return ParseProject(ctx)
        }
@@ -148,19 +158,19 @@ func ParseTargetProject(ctx context.Context) string {
 }
 
 func SetDomain(ctx context.Context, domain string) context.Context {
-       return SetContext(ctx, "domain", domain)
+       return SetContext(ctx, CtxDomain, domain)
 }
 
 func SetProject(ctx context.Context, project string) context.Context {
-       return SetContext(ctx, "project", project)
+       return SetContext(ctx, CtxProject, project)
 }
 
 func SetTargetDomain(ctx context.Context, domain string) context.Context {
-       return SetContext(ctx, "target-domain", domain)
+       return SetContext(ctx, CtxTargetDomain, domain)
 }
 
 func SetTargetProject(ctx context.Context, project string) context.Context {
-       return SetContext(ctx, "target-project", project)
+       return SetContext(ctx, CtxTargetProject, project)
 }
 
 func SetDomainProject(ctx context.Context, domain string, project string) 
context.Context {
diff --git a/pkg/util/context_grpc.go b/pkg/util/context_grpc.go
new file mode 100644
index 0000000..d2badb6
--- /dev/null
+++ b/pkg/util/context_grpc.go
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import (
+       "golang.org/x/net/context"
+       "google.golang.org/grpc/metadata"
+)
+
+func FromMetadata(ctx context.Context, key string) string {
+       md, ok := metadata.FromIncomingContext(ctx)
+       if !ok {
+               return ""
+       }
+       if values, ok := md[key]; ok && len(values) > 0 {
+               return values[0]
+       }
+       return ""
+}
diff --git a/pkg/util/context_grpc_test.go b/pkg/util/context_grpc_test.go
new file mode 100644
index 0000000..e97b7c0
--- /dev/null
+++ b/pkg/util/context_grpc_test.go
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package util
+
+import (
+       "context"
+       "google.golang.org/grpc/metadata"
+       "testing"
+)
+
+func TestFromMetadata(t *testing.T) {
+       v := FromMetadata(context.Background(), "a")
+       if v != "" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+       ctx := context.WithValue(context.Background(), "a", "b")
+       v = FromMetadata(ctx, "a")
+       if v != "" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+       ctx = metadata.NewIncomingContext(ctx, metadata.MD{})
+       v = FromMetadata(ctx, "a")
+       if v != "" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+       ctx = metadata.NewIncomingContext(ctx, metadata.MD{"a": []string{}})
+       v = FromMetadata(ctx, "a")
+       if v != "" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+       ctx = metadata.NewIncomingContext(ctx, metadata.MD{"a": []string{"b", 
"c"}})
+       v = FromMetadata(ctx, "a")
+       if v != "b" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+
+       // clone
+       cloneCtx := CloneContext(ctx)
+       v = FromMetadata(cloneCtx, "a")
+       if v != "b" {
+               t.Fatalf("TestFromMetadata failed")
+       }
+}
diff --git a/server/handler/context/v3.go b/server/handler/context/v3.go
index f063006..843e995 100644
--- a/server/handler/context/v3.go
+++ b/server/handler/context/v3.go
@@ -48,11 +48,11 @@ func (v *v3Context) Do(r *http.Request) error {
                        log.Errorf(err, "Invalid Request URI %s", r.RequestURI)
                        return err
                }
-               util.SetDomain(r.Context(), domain)
+               util.SetRequestContext(r, util.CtxDomain, domain)
        }
 
        if len(project) == 0 {
-               util.SetProject(r.Context(), core.REGISTRY_PROJECT)
+               util.SetRequestContext(r, util.CtxProject, 
core.REGISTRY_PROJECT)
        }
 
        return nil
diff --git a/server/handler/context/v4.go b/server/handler/context/v4.go
index 95b34df..710eb8c 100644
--- a/server/handler/context/v4.go
+++ b/server/handler/context/v4.go
@@ -44,7 +44,7 @@ func (v *v4Context) Do(r *http.Request) error {
                        log.Errorf(err, "Invalid Request URI %s", r.RequestURI)
                        return err
                }
-               util.SetDomain(r.Context(), domain)
+               util.SetRequestContext(r, util.CtxDomain, domain)
        }
 
        if len(project) == 0 {
@@ -52,7 +52,7 @@ func (v *v4Context) Do(r *http.Request) error {
                if len(project) == 0 {
                        project = core.REGISTRY_PROJECT
                }
-               util.SetProject(r.Context(), project)
+               util.SetRequestContext(r, util.CtxProject, project)
        }
 
        return nil
diff --git a/server/rest/controller/v4/instance_controller.go 
b/server/rest/controller/v4/instance_controller.go
index a6b4903..bfdd08a 100644
--- a/server/rest/controller/v4/instance_controller.go
+++ b/server/rest/controller/v4/instance_controller.go
@@ -137,14 +137,14 @@ func (this *MicroServiceInstanceService) FindInstances(w 
http.ResponseWriter, r
                Tags:              ids,
        }
 
-       util.SetTargetDomainProject(r.Context(), r.Header.Get("X-Domain-Name"), 
query.Get(":project"))
+       ctx := util.SetTargetDomainProject(r.Context(), 
r.Header.Get("X-Domain-Name"), query.Get(":project"))
 
-       resp, _ := core.InstanceAPI.Find(r.Context(), request)
+       resp, _ := core.InstanceAPI.Find(ctx, request)
        respInternal := resp.Response
        resp.Response = nil
 
-       iv, _ := r.Context().Value(serviceUtil.CTX_REQUEST_REVISION).(string)
-       ov, _ := r.Context().Value(serviceUtil.CTX_RESPONSE_REVISION).(string)
+       iv, _ := ctx.Value(serviceUtil.CTX_REQUEST_REVISION).(string)
+       ov, _ := ctx.Value(serviceUtil.CTX_RESPONSE_REVISION).(string)
        w.Header().Set(serviceUtil.HEADER_REV, ov)
        if len(iv) > 0 && iv == ov {
                w.WriteHeader(http.StatusNotModified)
diff --git a/server/service/instance.go b/server/service/instance.go
index eddd312..893bfb8 100644
--- a/server/service/instance.go
+++ b/server/service/instance.go
@@ -555,7 +555,7 @@ func (s *InstanceService) Find(ctx context.Context, in 
*pb.FindInstancesRequest)
        } else {
                // provider is not a shared micro-service,
                // only allow shared micro-service instances found in different 
domains.
-               util.SetTargetDomainProject(ctx, util.ParseDomain(ctx), 
util.ParseProject(ctx))
+               ctx = util.SetTargetDomainProject(ctx, util.ParseDomain(ctx), 
util.ParseProject(ctx))
                provider.Tenant = util.ParseTargetDomainProject(ctx)
 
                findFlag = func() string {

Reply via email to