/
ratelimit.go
148 lines (136 loc) · 4.08 KB
/
ratelimit.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
/**
* Tencent is pleased to support the open source community by making Polaris available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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 model
import (
"encoding/json"
"time"
apimodel "github.com/polarismesh/specification/source/go/api/v1/model"
apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage"
)
// RateLimit 限流规则
type RateLimit struct {
Proto *apitraffic.Rule
ID string
ServiceID string
Name string
Method string
// Labels for old compatible, will be removed later
Labels string
Priority uint32
Rule string
Revision string
Disable bool
Valid bool
CreateTime time.Time
ModifyTime time.Time
EnableTime time.Time
}
// Labels2Arguments 适配老的标签到新的参数列表
func (r *RateLimit) Labels2Arguments() (map[string]*apimodel.MatchString, error) {
if len(r.Proto.Arguments) == 0 && len(r.Labels) > 0 {
var labels = make(map[string]*apimodel.MatchString)
if err := json.Unmarshal([]byte(r.Labels), &labels); err != nil {
return nil, err
}
for key, value := range labels {
r.Proto.Arguments = append(r.Proto.Arguments, &apitraffic.MatchArgument{
Type: apitraffic.MatchArgument_CUSTOM,
Key: key,
Value: value,
})
}
return labels, nil
}
return nil, nil
}
const (
LabelKeyPath = "$path"
LabelKeyMethod = "$method"
LabelKeyHeader = "$header"
LabelKeyQuery = "$query"
LabelKeyCallerService = "$caller_service"
LabelKeyCallerIP = "$caller_ip"
)
// Arguments2Labels 将参数列表适配成旧的标签模型
func Arguments2Labels(arguments []*apitraffic.MatchArgument) map[string]*apimodel.MatchString {
if len(arguments) > 0 {
var labels = make(map[string]*apimodel.MatchString)
for _, argument := range arguments {
key := BuildArgumentKey(argument.Type, argument.Key)
labels[key] = argument.Value
}
return labels
}
return nil
}
func BuildArgumentKey(argumentType apitraffic.MatchArgument_Type, key string) string {
switch argumentType {
case apitraffic.MatchArgument_HEADER:
return LabelKeyHeader + "." + key
case apitraffic.MatchArgument_QUERY:
return LabelKeyQuery + "." + key
case apitraffic.MatchArgument_CALLER_SERVICE:
return LabelKeyCallerService + "." + key
case apitraffic.MatchArgument_CALLER_IP:
return LabelKeyCallerIP
case apitraffic.MatchArgument_CUSTOM:
return key
case apitraffic.MatchArgument_METHOD:
return LabelKeyMethod
default:
return key
}
}
// AdaptArgumentsAndLabels 对存量标签进行兼容,同时将argument适配成标签
func (r *RateLimit) AdaptArgumentsAndLabels() error {
// 新的限流规则,需要适配老的SDK使用场景
labels := Arguments2Labels(r.Proto.GetArguments())
if len(labels) > 0 {
r.Proto.Labels = labels
} else {
var err error
// 存量限流规则,需要适配成新的规则
labels, err = r.Labels2Arguments()
if nil != err {
return err
}
r.Proto.Labels = labels
}
return nil
}
// AdaptLabels 对存量标签进行兼容,对存量labels进行清空
func (r *RateLimit) AdaptLabels() error {
// 存量限流规则,需要适配成新的规则
_, err := r.Labels2Arguments()
if nil != err {
return err
}
r.Proto.Labels = nil
return nil
}
// ExtendRateLimit 包含服务信息的限流规则
type ExtendRateLimit struct {
ServiceName string
NamespaceName string
RateLimit *RateLimit
}
// RateLimitRevision 包含最新版本号的限流规则
type RateLimitRevision struct {
ServiceID string
LastRevision string
ModifyTime time.Time
}