github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/testutils/fakeserver/server.go (about) 1 /* 2 * 3 * Copyright 2019 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package fakeserver provides a fake implementation of the management server. 20 package fakeserver 21 22 import ( 23 "fmt" 24 "io" 25 "net" 26 "time" 27 28 "github.com/golang/protobuf/proto" 29 grpc "github.com/hxx258456/ccgo/grpc" 30 "github.com/hxx258456/ccgo/grpc/codes" 31 "github.com/hxx258456/ccgo/grpc/internal/testutils" 32 "github.com/hxx258456/ccgo/grpc/status" 33 34 discoverypb "github.com/hxx258456/ccgo/go-control-plane/envoy/api/v2" 35 adsgrpc "github.com/hxx258456/ccgo/go-control-plane/envoy/service/discovery/v2" 36 lrsgrpc "github.com/hxx258456/ccgo/go-control-plane/envoy/service/load_stats/v2" 37 lrspb "github.com/hxx258456/ccgo/go-control-plane/envoy/service/load_stats/v2" 38 ) 39 40 const ( 41 // TODO: Make this a var or a field in the server if there is a need to use a 42 // value other than this default. 43 defaultChannelBufferSize = 50 44 defaultDialTimeout = 5 * time.Second 45 ) 46 47 // Request wraps the request protobuf (xds/LRS) and error received by the 48 // Server in a call to stream.Recv(). 49 type Request struct { 50 Req proto.Message 51 Err error 52 } 53 54 // Response wraps the response protobuf (xds/LRS) and error that the Server 55 // should send out to the client through a call to stream.Send() 56 type Response struct { 57 Resp proto.Message 58 Err error 59 } 60 61 // Server is a fake implementation of xDS and LRS protocols. It listens on the 62 // same port for both services and exposes a bunch of channels to send/receive 63 // messages. 64 type Server struct { 65 // XDSRequestChan is a channel on which received xDS requests are made 66 // available to the users of this Server. 67 XDSRequestChan *testutils.Channel 68 // XDSResponseChan is a channel on which the Server accepts xDS responses 69 // to be sent to the client. 70 XDSResponseChan chan *Response 71 // LRSRequestChan is a channel on which received LRS requests are made 72 // available to the users of this Server. 73 LRSRequestChan *testutils.Channel 74 // LRSResponseChan is a channel on which the Server accepts the LRS 75 // response to be sent to the client. 76 LRSResponseChan chan *Response 77 // NewConnChan is a channel on which the fake server notifies receipt of new 78 // connection attempts. Tests can gate on this event before proceeding to 79 // other actions which depend on a connection to the fake server being up. 80 NewConnChan *testutils.Channel 81 // Address is the host:port on which the Server is listening for requests. 82 Address string 83 84 // The underlying fake implementation of xDS and LRS. 85 xdsS *xdsServer 86 lrsS *lrsServer 87 } 88 89 type wrappedListener struct { 90 net.Listener 91 server *Server 92 } 93 94 func (wl *wrappedListener) Accept() (net.Conn, error) { 95 c, err := wl.Listener.Accept() 96 if err != nil { 97 return nil, err 98 } 99 wl.server.NewConnChan.Send(struct{}{}) 100 return c, err 101 } 102 103 // StartServer makes a new Server and gets it to start listening on a local 104 // port for gRPC requests. The returned cancel function should be invoked by 105 // the caller upon completion of the test. 106 func StartServer() (*Server, func(), error) { 107 lis, err := net.Listen("tcp", "localhost:0") 108 if err != nil { 109 return nil, func() {}, fmt.Errorf("net.Listen() failed: %v", err) 110 } 111 112 s := &Server{ 113 XDSRequestChan: testutils.NewChannelWithSize(defaultChannelBufferSize), 114 LRSRequestChan: testutils.NewChannelWithSize(defaultChannelBufferSize), 115 NewConnChan: testutils.NewChannelWithSize(defaultChannelBufferSize), 116 XDSResponseChan: make(chan *Response, defaultChannelBufferSize), 117 LRSResponseChan: make(chan *Response, 1), // The server only ever sends one response. 118 Address: lis.Addr().String(), 119 } 120 s.xdsS = &xdsServer{reqChan: s.XDSRequestChan, respChan: s.XDSResponseChan} 121 s.lrsS = &lrsServer{reqChan: s.LRSRequestChan, respChan: s.LRSResponseChan} 122 wp := &wrappedListener{ 123 Listener: lis, 124 server: s, 125 } 126 127 server := grpc.NewServer() 128 lrsgrpc.RegisterLoadReportingServiceServer(server, s.lrsS) 129 adsgrpc.RegisterAggregatedDiscoveryServiceServer(server, s.xdsS) 130 go server.Serve(wp) 131 132 return s, func() { server.Stop() }, nil 133 } 134 135 type xdsServer struct { 136 reqChan *testutils.Channel 137 respChan chan *Response 138 } 139 140 func (xdsS *xdsServer) StreamAggregatedResources(s adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesServer) error { 141 errCh := make(chan error, 2) 142 go func() { 143 for { 144 req, err := s.Recv() 145 if err != nil { 146 errCh <- err 147 return 148 } 149 xdsS.reqChan.Send(&Request{req, err}) 150 } 151 }() 152 go func() { 153 var retErr error 154 defer func() { 155 errCh <- retErr 156 }() 157 158 for { 159 select { 160 case r := <-xdsS.respChan: 161 if r.Err != nil { 162 retErr = r.Err 163 return 164 } 165 if err := s.Send(r.Resp.(*discoverypb.DiscoveryResponse)); err != nil { 166 retErr = err 167 return 168 } 169 case <-s.Context().Done(): 170 retErr = s.Context().Err() 171 return 172 } 173 } 174 }() 175 176 if err := <-errCh; err != nil { 177 return err 178 } 179 return nil 180 } 181 182 func (xdsS *xdsServer) DeltaAggregatedResources(adsgrpc.AggregatedDiscoveryService_DeltaAggregatedResourcesServer) error { 183 return status.Error(codes.Unimplemented, "") 184 } 185 186 type lrsServer struct { 187 reqChan *testutils.Channel 188 respChan chan *Response 189 } 190 191 func (lrsS *lrsServer) StreamLoadStats(s lrsgrpc.LoadReportingService_StreamLoadStatsServer) error { 192 req, err := s.Recv() 193 lrsS.reqChan.Send(&Request{req, err}) 194 if err != nil { 195 return err 196 } 197 198 select { 199 case r := <-lrsS.respChan: 200 if r.Err != nil { 201 return r.Err 202 } 203 if err := s.Send(r.Resp.(*lrspb.LoadStatsResponse)); err != nil { 204 return err 205 } 206 case <-s.Context().Done(): 207 return s.Context().Err() 208 } 209 210 for { 211 req, err := s.Recv() 212 lrsS.reqChan.Send(&Request{req, err}) 213 if err != nil { 214 if err == io.EOF { 215 return nil 216 } 217 return err 218 } 219 } 220 }