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  }