-
Notifications
You must be signed in to change notification settings - Fork 208
/
Copy pathapi_common.go
141 lines (114 loc) · 4.03 KB
/
api_common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package internal
import (
"context"
"errors"
"os"
"github.com/golang/protobuf/proto"
)
type ctxKey string
func (c ctxKey) String() string {
return "appengine context key: " + string(c)
}
var errNotAppEngineContext = errors.New("not an App Engine context")
type CallOverrideFunc func(ctx context.Context, service, method string, in, out proto.Message) error
var callOverrideKey = "holds []CallOverrideFunc"
func WithCallOverride(ctx context.Context, f CallOverrideFunc) context.Context {
// We avoid appending to any existing call override
// so we don't risk overwriting a popped stack below.
var cofs []CallOverrideFunc
if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok {
cofs = append(cofs, uf...)
}
cofs = append(cofs, f)
return context.WithValue(ctx, &callOverrideKey, cofs)
}
func callOverrideFromContext(ctx context.Context) (CallOverrideFunc, context.Context, bool) {
cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc)
if len(cofs) == 0 {
return nil, nil, false
}
// We found a list of overrides; grab the last, and reconstitute a
// context that will hide it.
f := cofs[len(cofs)-1]
ctx = context.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1])
return f, ctx, true
}
type logOverrideFunc func(level int64, format string, args ...interface{})
var logOverrideKey = "holds a logOverrideFunc"
func WithLogOverride(ctx context.Context, f logOverrideFunc) context.Context {
return context.WithValue(ctx, &logOverrideKey, f)
}
var appIDOverrideKey = "holds a string, being the full app ID"
func WithAppIDOverride(ctx context.Context, appID string) context.Context {
return context.WithValue(ctx, &appIDOverrideKey, appID)
}
var apiHostOverrideKey = ctxKey("holds a string, being the alternate API_HOST")
func withAPIHostOverride(ctx context.Context, apiHost string) context.Context {
return context.WithValue(ctx, apiHostOverrideKey, apiHost)
}
var apiPortOverrideKey = ctxKey("holds a string, being the alternate API_PORT")
func withAPIPortOverride(ctx context.Context, apiPort string) context.Context {
return context.WithValue(ctx, apiPortOverrideKey, apiPort)
}
var namespaceKey = "holds the namespace string"
func withNamespace(ctx context.Context, ns string) context.Context {
return context.WithValue(ctx, &namespaceKey, ns)
}
func NamespaceFromContext(ctx context.Context) string {
// If there's no namespace, return the empty string.
ns, _ := ctx.Value(&namespaceKey).(string)
return ns
}
// FullyQualifiedAppID returns the fully-qualified application ID.
// This may contain a partition prefix (e.g. "s~" for High Replication apps),
// or a domain prefix (e.g. "example.com:").
func FullyQualifiedAppID(ctx context.Context) string {
if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
return id
}
return fullyQualifiedAppID(ctx)
}
func Logf(ctx context.Context, level int64, format string, args ...interface{}) {
if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok {
f(level, format, args...)
return
}
c := fromContext(ctx)
if c == nil {
panic(errNotAppEngineContext)
}
logf(c, level, format, args...)
}
// NamespacedContext wraps a Context to support namespaces.
func NamespacedContext(ctx context.Context, namespace string) context.Context {
return withNamespace(ctx, namespace)
}
// SetTestEnv sets the env variables for testing background ticket in Flex.
func SetTestEnv() func() {
var environ = []struct {
key, value string
}{
{"GAE_LONG_APP_ID", "my-app-id"},
{"GAE_MINOR_VERSION", "067924799508853122"},
{"GAE_MODULE_INSTANCE", "0"},
{"GAE_MODULE_NAME", "default"},
{"GAE_MODULE_VERSION", "20150612t184001"},
}
for _, v := range environ {
old := os.Getenv(v.key)
os.Setenv(v.key, v.value)
v.value = old
}
return func() { // Restore old environment after the test completes.
for _, v := range environ {
if v.value == "" {
os.Unsetenv(v.key)
continue
}
os.Setenv(v.key, v.value)
}
}
}