github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/google.golang.org/appengine/internal/api_common.go (about) 1 // Copyright 2015 Google Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 package internal 6 7 import ( 8 "github.com/golang/protobuf/proto" 9 netcontext "golang.org/x/net/context" 10 ) 11 12 type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error 13 14 var callOverrideKey = "holds []CallOverrideFunc" 15 16 func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context { 17 // We avoid appending to any existing call override 18 // so we don't risk overwriting a popped stack below. 19 var cofs []CallOverrideFunc 20 if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok { 21 cofs = append(cofs, uf...) 22 } 23 cofs = append(cofs, f) 24 return netcontext.WithValue(ctx, &callOverrideKey, cofs) 25 } 26 27 func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) { 28 cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc) 29 if len(cofs) == 0 { 30 return nil, nil, false 31 } 32 // We found a list of overrides; grab the last, and reconstitute a 33 // context that will hide it. 34 f := cofs[len(cofs)-1] 35 ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1]) 36 return f, ctx, true 37 } 38 39 type logOverrideFunc func(level int64, format string, args ...interface{}) 40 41 var logOverrideKey = "holds a logOverrideFunc" 42 43 func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context { 44 return netcontext.WithValue(ctx, &logOverrideKey, f) 45 } 46 47 var appIDOverrideKey = "holds a string, being the full app ID" 48 49 func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context { 50 return netcontext.WithValue(ctx, &appIDOverrideKey, appID) 51 } 52 53 var namespaceKey = "holds the namespace string" 54 55 func withNamespace(ctx netcontext.Context, ns string) netcontext.Context { 56 return netcontext.WithValue(ctx, &namespaceKey, ns) 57 } 58 59 func NamespaceFromContext(ctx netcontext.Context) string { 60 // If there's no namespace, return the empty string. 61 ns, _ := ctx.Value(&namespaceKey).(string) 62 return ns 63 } 64 65 // FullyQualifiedAppID returns the fully-qualified application ID. 66 // This may contain a partition prefix (e.g. "s~" for High Replication apps), 67 // or a domain prefix (e.g. "example.com:"). 68 func FullyQualifiedAppID(ctx netcontext.Context) string { 69 if id, ok := ctx.Value(&appIDOverrideKey).(string); ok { 70 return id 71 } 72 return fullyQualifiedAppID(ctx) 73 } 74 75 func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) { 76 if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok { 77 f(level, format, args...) 78 return 79 } 80 logf(fromContext(ctx), level, format, args...) 81 } 82 83 // NamespacedContext wraps a Context to support namespaces. 84 func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context { 85 n := &namespacedContext{ 86 namespace: namespace, 87 } 88 return withNamespace(WithCallOverride(ctx, n.call), namespace) 89 } 90 91 type namespacedContext struct { 92 namespace string 93 } 94 95 func (n *namespacedContext) call(ctx netcontext.Context, service, method string, in, out proto.Message) error { 96 // Apply any namespace mods. 97 if mod, ok := NamespaceMods[service]; ok { 98 mod(in, n.namespace) 99 } 100 return Call(ctx, service, method, in, out) 101 }