github.com/polarismesh/polaris@v1.17.8/apiserver/grpcserver/discover/v1/client_access.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 "context" 22 "fmt" 23 "io" 24 "strings" 25 26 apimodel "github.com/polarismesh/specification/source/go/api/v1/model" 27 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 28 "go.uber.org/zap" 29 "google.golang.org/grpc" 30 "google.golang.org/grpc/metadata" 31 "google.golang.org/grpc/peer" 32 33 "github.com/polarismesh/polaris/apiserver/grpcserver" 34 api "github.com/polarismesh/polaris/common/api/v1" 35 commonlog "github.com/polarismesh/polaris/common/log" 36 "github.com/polarismesh/polaris/common/utils" 37 ) 38 39 var ( 40 accesslog = commonlog.GetScopeOrDefaultByName(commonlog.APIServerLoggerName) 41 ) 42 43 // ReportClient 客户端上报 44 func (g *DiscoverServer) ReportClient(ctx context.Context, in *apiservice.Client) (*apiservice.Response, error) { 45 return g.namingServer.ReportClient(grpcserver.ConvertContext(ctx), in), nil 46 } 47 48 // RegisterInstance 注册服务实例 49 func (g *DiscoverServer) RegisterInstance(ctx context.Context, in *apiservice.Instance) (*apiservice.Response, error) { 50 // 需要记录操作来源,提高效率,只针对特殊接口添加operator 51 rCtx := grpcserver.ConvertContext(ctx) 52 rCtx = context.WithValue(rCtx, utils.StringContext("operator"), ParseGrpcOperator(ctx)) 53 54 // 客户端请求中带了 token 的,优先已请求中的为准 55 if in.GetServiceToken().GetValue() != "" { 56 rCtx = context.WithValue(rCtx, utils.ContextAuthTokenKey, in.GetServiceToken().GetValue()) 57 } 58 59 grpcHeader := rCtx.Value(utils.ContextGrpcHeader).(metadata.MD) 60 61 if _, ok := grpcHeader["async-regis"]; ok { 62 rCtx = context.WithValue(rCtx, utils.ContextOpenAsyncRegis, true) 63 } 64 65 out := g.namingServer.RegisterInstance(rCtx, in) 66 return out, nil 67 } 68 69 // DeregisterInstance 反注册服务实例 70 func (g *DiscoverServer) DeregisterInstance( 71 ctx context.Context, in *apiservice.Instance) (*apiservice.Response, error) { 72 // 需要记录操作来源,提高效率,只针对特殊接口添加operator 73 rCtx := grpcserver.ConvertContext(ctx) 74 rCtx = context.WithValue(rCtx, utils.StringContext("operator"), ParseGrpcOperator(ctx)) 75 76 // 客户端请求中带了 token 的,优先已请求中的为准 77 if in.GetServiceToken().GetValue() != "" { 78 rCtx = context.WithValue(rCtx, utils.ContextAuthTokenKey, in.GetServiceToken().GetValue()) 79 } 80 81 out := g.namingServer.DeregisterInstance(rCtx, in) 82 return out, nil 83 } 84 85 // Discover 统一发现接口 86 func (g *DiscoverServer) Discover(server apiservice.PolarisGRPC_DiscoverServer) error { 87 ctx := grpcserver.ConvertContext(server.Context()) 88 clientIP, _ := ctx.Value(utils.StringContext("client-ip")).(string) 89 clientAddress, _ := ctx.Value(utils.StringContext("client-address")).(string) 90 requestID, _ := ctx.Value(utils.StringContext("request-id")).(string) 91 userAgent, _ := ctx.Value(utils.StringContext("user-agent")).(string) 92 method, _ := grpc.MethodFromServerStream(server) 93 94 for { 95 in, err := server.Recv() 96 if err != nil { 97 if io.EOF == err { 98 return nil 99 } 100 return err 101 } 102 103 msg := fmt.Sprintf("receive grpc discover request: %s", in.Service.String()) 104 accesslog.Info(msg, 105 zap.String("type", apiservice.DiscoverRequest_DiscoverRequestType_name[int32(in.Type)]), 106 zap.String("client-address", clientAddress), 107 zap.String("user-agent", userAgent), 108 utils.ZapRequestID(requestID), 109 ) 110 111 // 是否允许访问 112 if ok := g.allowAccess(method); !ok { 113 resp := api.NewDiscoverResponse(apimodel.Code_ClientAPINotOpen) 114 if sendErr := server.Send(resp); sendErr != nil { 115 return sendErr 116 } 117 continue 118 } 119 120 // stream模式,需要对每个包进行检测 121 if code := g.enterRateLimit(clientIP, method); code != uint32(apimodel.Code_ExecuteSuccess) { 122 resp := api.NewDiscoverResponse(apimodel.Code(code)) 123 if err = server.Send(resp); err != nil { 124 return err 125 } 126 continue 127 } 128 129 var out *apiservice.DiscoverResponse 130 switch in.Type { 131 case apiservice.DiscoverRequest_INSTANCE: 132 out = g.namingServer.ServiceInstancesCache(ctx, in.Service) 133 case apiservice.DiscoverRequest_ROUTING: 134 out = g.namingServer.GetRoutingConfigWithCache(ctx, in.Service) 135 case apiservice.DiscoverRequest_RATE_LIMIT: 136 out = g.namingServer.GetRateLimitWithCache(ctx, in.Service) 137 case apiservice.DiscoverRequest_CIRCUIT_BREAKER: 138 out = g.namingServer.GetCircuitBreakerWithCache(ctx, in.Service) 139 case apiservice.DiscoverRequest_SERVICES: 140 out = g.namingServer.GetServiceWithCache(ctx, in.Service) 141 case apiservice.DiscoverRequest_FAULT_DETECTOR: 142 out = g.namingServer.GetFaultDetectWithCache(ctx, in.Service) 143 default: 144 out = api.NewDiscoverRoutingResponse(apimodel.Code_InvalidDiscoverResource, in.Service) 145 } 146 147 err = server.Send(out) 148 if err != nil { 149 return err 150 } 151 } 152 } 153 154 // Heartbeat 上报心跳 155 func (g *DiscoverServer) Heartbeat(ctx context.Context, in *apiservice.Instance) (*apiservice.Response, error) { 156 return g.healthCheckServer.Report(grpcserver.ConvertContext(ctx), in), nil 157 } 158 159 // BatchHeartbeat 批量上报心跳 160 func (g *DiscoverServer) BatchHeartbeat(svr apiservice.PolarisHeartbeatGRPC_BatchHeartbeatServer) error { 161 ctx := grpcserver.ConvertContext(svr.Context()) 162 163 for { 164 req, err := svr.Recv() 165 if err != nil { 166 if io.EOF == err { 167 return nil 168 } 169 return err 170 } 171 172 _ = g.healthCheckServer.Reports(ctx, req.GetHeartbeats()) 173 if err = svr.Send(&apiservice.HeartbeatsResponse{}); err != nil { 174 return err 175 } 176 } 177 } 178 179 // ParseGrpcOperator 构造请求源 180 func ParseGrpcOperator(ctx context.Context) string { 181 // 获取请求源 182 operator := "GRPC" 183 if pr, ok := peer.FromContext(ctx); ok && pr.Addr != nil { 184 addrSlice := strings.Split(pr.Addr.String(), ":") 185 if len(addrSlice) == 2 { 186 operator += ":" + addrSlice[0] 187 } 188 } 189 return operator 190 }