aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/google.golang.org/appengine/internal/api_common.go
blob: e0c0b214b724212071f072eadd289c73af3d154b (plain) (blame)
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
// 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 (
    "errors"
    "os"

    "github.com/golang/protobuf/proto"
    netcontext "golang.org/x/net/context"
)

var errNotAppEngineContext = errors.New("not an App Engine context")

type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error

var callOverrideKey = "holds []CallOverrideFunc"

func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.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 netcontext.WithValue(ctx, &callOverrideKey, cofs)
}

func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.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 = netcontext.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 netcontext.Context, f logOverrideFunc) netcontext.Context {
    return netcontext.WithValue(ctx, &logOverrideKey, f)
}

var appIDOverrideKey = "holds a string, being the full app ID"

func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
    return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
}

var namespaceKey = "holds the namespace string"

func withNamespace(ctx netcontext.Context, ns string) netcontext.Context {
    return netcontext.WithValue(ctx, &namespaceKey, ns)
}

func NamespaceFromContext(ctx netcontext.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 netcontext.Context) string {
    if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
        return id
    }
    return fullyQualifiedAppID(ctx)
}

func Logf(ctx netcontext.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 netcontext.Context, namespace string) netcontext.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)
        }
    }
}