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 {