This repository has been archived by the owner on Apr 7, 2020. It is now read-only.
forked from istio/istio
-
Notifications
You must be signed in to change notification settings - Fork 152
/
handler.go
156 lines (131 loc) · 5.34 KB
/
handler.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2017 Istio Authors
//
// Licensed 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 mockapi
import (
"time"
rpc "github.com/gogo/googleapis/google/rpc"
mixerpb "istio.io/api/mixer/v1"
"istio.io/istio/mixer/pkg/attribute"
"istio.io/istio/mixer/pkg/status"
)
// AttributesHandler provides an interface for building custom testing behavior.
// AttributesHandlers are used by a test.AttributesServer to pass attribute bags
// to testing code for validation of proper transport using the Mixer API.
type AttributesHandler interface {
// Check will be called once per Mixer API Check() request.
Check(attribute.Bag) mixerpb.CheckResponse_PreconditionResult
// Quota will be called once per quota (with params) received in a Check()
// request.
Quota(attribute.Bag, QuotaArgs) (QuotaResponse, rpc.Status)
// Report will be called once per set of attributes received in a Report()
// request.
Report(attribute.Bag) rpc.Status
}
// ChannelsHandler sends received attribute.Bags (and other) information on the
// configured channels (with a timeout).
type ChannelsHandler struct {
AttributesHandler
// QuotaResponse controls the response returned as part of Quota() calls.
QuotaResponse QuotaResponse
// ReturnStatus controls the rpc.Status returned for Check(), Quota(), and
// Report() calls.
ReturnStatus rpc.Status
// CheckAttributes is the channel on which the attribute bag generated by
// the server for Check() requests is sent.
CheckAttributes chan attribute.Bag
// QuotaDispatches is the channel on which the quota information generated by
// the server for Check() requests is sent.
QuotaDispatches chan QuotaDispatchInfo
// ReportAttributes is the channel on which the attribute bag generated by
// the server for Report() requests is sent.
ReportAttributes chan attribute.Bag
}
// NewChannelsHandler creates a ChannelsHandler with channels of default length
// and default values for ReturnStatuses and QuotaResponses.
func NewChannelsHandler() *ChannelsHandler {
return &ChannelsHandler{
QuotaResponse: QuotaResponse{DefaultValidDuration, DefaultAmount, nil},
ReturnStatus: status.OK,
CheckAttributes: make(chan attribute.Bag),
QuotaDispatches: make(chan QuotaDispatchInfo),
ReportAttributes: make(chan attribute.Bag),
}
}
// Check implements AttributesHandler interface.
func (c *ChannelsHandler) Check(req attribute.Bag) mixerpb.CheckResponse_PreconditionResult {
// avoid blocked go-routines in testing
result := mixerpb.CheckResponse_PreconditionResult{
ValidDuration: DefaultValidDuration,
ValidUseCount: DefaultValidUseCount,
}
select {
case c.CheckAttributes <- attribute.CopyBag(req):
result.Status = c.ReturnStatus
case <-time.After(1 * time.Second):
result.Status = status.WithDeadlineExceeded("timeout sending to Check channel")
}
return result
}
// Quota implements AttributesHandler interface.
func (c *ChannelsHandler) Quota(req attribute.Bag, qma QuotaArgs) (QuotaResponse, rpc.Status) {
// avoid blocked go-routines in testing
select {
case c.QuotaDispatches <- QuotaDispatchInfo{attribute.CopyBag(req), qma}:
return c.QuotaResponse, c.ReturnStatus
case <-time.After(1 * time.Second):
return QuotaResponse{}, status.WithDeadlineExceeded("timeout sending to Quota channel")
}
}
// Report implements AttributesHandler interface.
func (c *ChannelsHandler) Report(req attribute.Bag) rpc.Status {
// avoid blocked go-routines in testing
select {
case c.ReportAttributes <- attribute.CopyBag(req):
return c.ReturnStatus
case <-time.After(1 * time.Second):
return status.WithDeadlineExceeded("timeout sending to Report channel")
}
}
// QuotaDispatchInfo contains both the attribute bag generated by the server
// for Quota dispatch, as well as the corresponding method arguments.
type QuotaDispatchInfo struct {
Attributes attribute.Bag
MethodArgs QuotaArgs
}
// QuotaArgs mirrors aspect.QuotaArgs. It allows tests to understand
// how their inputs map into quota calls within Mixer to validate the proper
// requests are being generated. It is NOT a contract for how a real Mixer would
// generate or dispatch Quota calls.
type QuotaArgs struct {
// Unique ID for Quota operation.
DeduplicationID string
// The quota to allocate from.
Quota string
// The amount of quota to allocate.
Amount int64
// If true, allows a response to return less quota than requested. When
// false, the exact requested amount is returned or 0 if not enough quota
// was available.
BestEffort bool
}
// QuotaResponse provides information on the result of a Quota operation. It allows testing
// to target precise quota responses.
type QuotaResponse struct {
// The amount of time until which the returned quota expires, this is 0 for non-expiring quotas.
Expiration time.Duration
// The total amount of quota returned, may be less than requested.
Amount int64
// Referenced attributes for client
Referenced *mixerpb.ReferencedAttributes
}