github.com/polarismesh/polaris@v1.17.8/common/api/v1/naming_response.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package v1 19 20 import ( 21 "github.com/golang/protobuf/proto" 22 "github.com/golang/protobuf/ptypes/wrappers" 23 apifault "github.com/polarismesh/specification/source/go/api/v1/fault_tolerance" 24 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 25 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 26 apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage" 27 "google.golang.org/protobuf/types/known/anypb" 28 ) 29 30 /** 31 * @brief 回复消息接口 32 */ 33 type ResponseMessage interface { 34 proto.Message 35 GetCode() *wrappers.UInt32Value 36 GetInfo() *wrappers.StringValue 37 } 38 39 /** 40 * @brief 获取返回码前三位 41 * @note 返回码前三位和HTTP返回码定义一致 42 */ 43 func CalcCode(rm ResponseMessage) int { 44 return int(rm.GetCode().GetValue() / 1000) 45 } 46 47 /** 48 * @brief BatchWriteResponse添加Response 49 */ 50 func Collect(batchWriteResponse *apiservice.BatchWriteResponse, response *apiservice.Response) { 51 // 非200的code,都归为异常 52 if CalcCode(response) != 200 { 53 if response.GetCode().GetValue() >= batchWriteResponse.GetCode().GetValue() { 54 batchWriteResponse.Code.Value = response.GetCode().GetValue() 55 batchWriteResponse.Info.Value = code2info[batchWriteResponse.GetCode().GetValue()] 56 } 57 } 58 59 batchWriteResponse.Size.Value++ 60 batchWriteResponse.Responses = append(batchWriteResponse.Responses, response) 61 } 62 63 // AddNamespace BatchQueryResponse添加命名空间 64 func AddNamespace(b *apiservice.BatchQueryResponse, namespace *apimodel.Namespace) { 65 b.Namespaces = append(b.Namespaces, namespace) 66 } 67 68 // AddNamespaceSummary 添加汇总信息 69 func AddNamespaceSummary(b *apiservice.BatchQueryResponse, summary *apimodel.Summary) { 70 b.Summary = summary 71 } 72 73 // NewResponse 创建回复 74 func NewResponse(code apimodel.Code) *apiservice.Response { 75 return &apiservice.Response{ 76 Code: &wrappers.UInt32Value{Value: uint32(code)}, 77 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 78 } 79 } 80 81 // NewResponseWithMsg 带上具体的错误信息 82 func NewResponseWithMsg(code apimodel.Code, msg string) *apiservice.Response { 83 resp := NewResponse(code) 84 resp.Info.Value += ": " + msg 85 return resp 86 } 87 88 /** 89 * @brief 创建回复带客户端信息 90 */ 91 func NewClientResponse(code apimodel.Code, client *apiservice.Client) *apiservice.Response { 92 return &apiservice.Response{ 93 Code: &wrappers.UInt32Value{Value: uint32(code)}, 94 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 95 Client: client, 96 } 97 } 98 99 /** 100 * @brief 创建回复带命名空间信息 101 */ 102 func NewNamespaceResponse(code apimodel.Code, namespace *apimodel.Namespace) *apiservice.Response { 103 return &apiservice.Response{ 104 Code: &wrappers.UInt32Value{Value: uint32(code)}, 105 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 106 Namespace: namespace, 107 } 108 } 109 110 /** 111 * @brief 创建回复带服务信息 112 */ 113 func NewServiceResponse(code apimodel.Code, service *apiservice.Service) *apiservice.Response { 114 return &apiservice.Response{ 115 Code: &wrappers.UInt32Value{Value: uint32(code)}, 116 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 117 Service: service, 118 } 119 } 120 121 // 创建带别名信息的答复 122 func NewServiceAliasResponse(code apimodel.Code, alias *apiservice.ServiceAlias) *apiservice.Response { 123 resp := NewResponse(code) 124 resp.Alias = alias 125 return resp 126 } 127 128 /** 129 * @brief 创建回复带服务实例信息 130 */ 131 func NewInstanceResponse(code apimodel.Code, instance *apiservice.Instance) *apiservice.Response { 132 return &apiservice.Response{ 133 Code: &wrappers.UInt32Value{Value: uint32(code)}, 134 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 135 Instance: instance, 136 } 137 } 138 139 // 创建带自定义error的服务实例response 140 func NewInstanceRespWithError(code apimodel.Code, err error, instance *apiservice.Instance) *apiservice.Response { 141 resp := NewInstanceResponse(code, instance) 142 resp.Info.Value += " : " + err.Error() 143 144 return resp 145 } 146 147 /** 148 * @brief 创建回复带服务路由信息 149 */ 150 func NewRoutingResponse(code apimodel.Code, routing *apitraffic.Routing) *apiservice.Response { 151 return &apiservice.Response{ 152 Code: &wrappers.UInt32Value{Value: uint32(code)}, 153 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 154 Routing: routing, 155 } 156 } 157 158 // NewAnyDataResponse create the response with data with any type 159 func NewAnyDataResponse(code apimodel.Code, msg proto.Message) *apiservice.Response { 160 ret, err := anypb.New(proto.MessageV2(msg)) 161 if err != nil { 162 return NewResponse(code) 163 } 164 return &apiservice.Response{ 165 Code: &wrappers.UInt32Value{Value: uint32(code)}, 166 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 167 Data: ret, 168 } 169 } 170 171 // NewRouterResponse 创建带新版本路由的返回 172 func NewRouterResponse(code apimodel.Code, router *apitraffic.RouteRule) *apiservice.Response { 173 return NewAnyDataResponse(code, router) 174 } 175 176 // NewRateLimitResponse 创建回复带限流规则信息 177 func NewRateLimitResponse(code apimodel.Code, rule *apitraffic.Rule) *apiservice.Response { 178 return &apiservice.Response{ 179 Code: &wrappers.UInt32Value{Value: uint32(code)}, 180 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 181 RateLimit: rule, 182 } 183 } 184 185 /** 186 * @brief 创建回复带熔断规则信息 187 */ 188 func NewCircuitBreakerResponse(code apimodel.Code, circuitBreaker *apifault.CircuitBreaker) *apiservice.Response { 189 return &apiservice.Response{ 190 Code: &wrappers.UInt32Value{Value: uint32(code)}, 191 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 192 CircuitBreaker: circuitBreaker, 193 } 194 } 195 196 /** 197 * @brief 创建批量回复 198 */ 199 func NewBatchWriteResponse(code apimodel.Code) *apiservice.BatchWriteResponse { 200 return &apiservice.BatchWriteResponse{ 201 Code: &wrappers.UInt32Value{Value: uint32(code)}, 202 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 203 Size: &wrappers.UInt32Value{Value: 0}, 204 } 205 } 206 207 /** 208 * @brief 创建带详细信息的批量回复 209 */ 210 func NewBatchWriteResponseWithMsg(code apimodel.Code, msg string) *apiservice.BatchWriteResponse { 211 resp := NewBatchWriteResponse(code) 212 resp.Info.Value += ": " + msg 213 return resp 214 } 215 216 // NewBatchQueryResponse create the batch query responses 217 func NewBatchQueryResponse(code apimodel.Code) *apiservice.BatchQueryResponse { 218 return &apiservice.BatchQueryResponse{ 219 Code: &wrappers.UInt32Value{Value: uint32(code)}, 220 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 221 Amount: &wrappers.UInt32Value{Value: 0}, 222 Size: &wrappers.UInt32Value{Value: 0}, 223 } 224 } 225 226 // NewBatchQueryResponseWithMsg create the batch query responses with message 227 func NewBatchQueryResponseWithMsg(code apimodel.Code, msg string) *apiservice.BatchQueryResponse { 228 resp := NewBatchQueryResponse(code) 229 resp.Info.Value += ": " + msg 230 return resp 231 } 232 233 // AddAnyDataIntoBatchQuery add message as any data array 234 func AddAnyDataIntoBatchQuery(resp *apiservice.BatchQueryResponse, message proto.Message) error { 235 ret, err := anypb.New(proto.MessageV2(message)) 236 if err != nil { 237 return err 238 } 239 resp.Data = append(resp.Data, ret) 240 return nil 241 } 242 243 // 创建一个空白的discoverResponse 244 func NewDiscoverResponse(code apimodel.Code) *apiservice.DiscoverResponse { 245 return &apiservice.DiscoverResponse{ 246 Code: &wrappers.UInt32Value{Value: uint32(code)}, 247 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 248 } 249 } 250 251 /** 252 * @brief 创建查询服务回复 253 */ 254 func NewDiscoverServiceResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 255 return &apiservice.DiscoverResponse{ 256 Code: &wrappers.UInt32Value{Value: uint32(code)}, 257 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 258 Type: apiservice.DiscoverResponse_SERVICES, 259 Service: service, 260 } 261 } 262 263 /** 264 * @brief 创建查询服务实例回复 265 */ 266 func NewDiscoverInstanceResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 267 return &apiservice.DiscoverResponse{ 268 Code: &wrappers.UInt32Value{Value: uint32(code)}, 269 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 270 Type: apiservice.DiscoverResponse_INSTANCE, 271 Service: service, 272 } 273 } 274 275 /** 276 * @brief 创建查询服务路由回复 277 */ 278 func NewDiscoverRoutingResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 279 return &apiservice.DiscoverResponse{ 280 Code: &wrappers.UInt32Value{Value: uint32(code)}, 281 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 282 Type: apiservice.DiscoverResponse_ROUTING, 283 Service: service, 284 } 285 } 286 287 /** 288 * @brief 创建查询限流规则回复 289 */ 290 func NewDiscoverRateLimitResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 291 return &apiservice.DiscoverResponse{ 292 Code: &wrappers.UInt32Value{Value: uint32(code)}, 293 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 294 Type: apiservice.DiscoverResponse_RATE_LIMIT, 295 Service: service, 296 } 297 } 298 299 /** 300 * @brief 创建查询熔断规则回复 301 */ 302 func NewDiscoverCircuitBreakerResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 303 return &apiservice.DiscoverResponse{ 304 Code: &wrappers.UInt32Value{Value: uint32(code)}, 305 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 306 Type: apiservice.DiscoverResponse_CIRCUIT_BREAKER, 307 Service: service, 308 } 309 } 310 311 /** 312 * @brief 创建查询探测规则回复 313 */ 314 func NewDiscoverFaultDetectorResponse(code apimodel.Code, service *apiservice.Service) *apiservice.DiscoverResponse { 315 return &apiservice.DiscoverResponse{ 316 Code: &wrappers.UInt32Value{Value: uint32(code)}, 317 Info: &wrappers.StringValue{Value: code2info[uint32(code)]}, 318 Type: apiservice.DiscoverResponse_FAULT_DETECTOR, 319 Service: service, 320 } 321 } 322 323 // 格式化responses 324 // batch操作 325 // 如果所有子错误码一致,那么使用子错误码 326 // 如果包含任意一个5xx,那么返回500 327 func FormatBatchWriteResponse(response *apiservice.BatchWriteResponse) *apiservice.BatchWriteResponse { 328 var code uint32 329 for _, resp := range response.Responses { 330 if code == 0 { 331 code = resp.GetCode().GetValue() 332 continue 333 } 334 if code == resp.GetCode().GetValue() { 335 continue 336 } 337 // 发现不一样 338 code = 0 339 break 340 } 341 // code不等于0,意味着所有的resp都是一样的错误码,则合并为同一个错误码 342 if code != 0 { 343 response.Code.Value = code 344 response.Info.Value = code2info[code] 345 return response 346 } 347 348 // 错误都不一致 349 // 存在5XX,则返回500 350 // 不存在5XX,但是存在4XX,则返回4XX 351 // 除去以上两个情况,不修改返回值 352 hasBadRequest := false 353 for _, resp := range response.Responses { 354 httpStatus := CalcCode(resp) 355 if httpStatus >= 500 { 356 response.Code.Value = ExecuteException 357 response.Info.Value = code2info[response.Code.Value] 358 return response 359 } else if httpStatus >= 400 { 360 hasBadRequest = true 361 } 362 } 363 364 if hasBadRequest { 365 response.Code.Value = BadRequest 366 response.Info.Value = code2info[response.Code.Value] 367 } 368 return response 369 }