11/*
22 *
3- * Copyright 2020 gRPC authors.
3+ * Copyright 2021 gRPC authors.
44 *
55 * Licensed under the Apache License, Version 2.0 (the "License");
66 * you may not use this file except in compliance with the License.
1616 *
1717 */
1818
19- // Binary server for xDS interop tests.
19+ // Binary server is the server used for xDS interop tests.
2020package main
2121
2222import (
2323 "context"
2424 "flag"
25+ "fmt"
2526 "log"
2627 "net"
2728 "os"
28- "strconv"
2929
3030 "google.golang.org/grpc"
31+ "google.golang.org/grpc/admin"
32+ "google.golang.org/grpc/credentials/insecure"
3133 "google.golang.org/grpc/grpclog"
34+ "google.golang.org/grpc/health"
3235 "google.golang.org/grpc/metadata"
36+ "google.golang.org/grpc/reflection"
37+ "google.golang.org/grpc/xds"
3338
39+ xdscreds "google.golang.org/grpc/credentials/xds"
40+ healthpb "google.golang.org/grpc/health/grpc_health_v1"
3441 testgrpc "google.golang.org/grpc/interop/grpc_testing"
3542 testpb "google.golang.org/grpc/interop/grpc_testing"
3643)
3744
3845var (
39- port = flag .Int ("port" , 8080 , "The server port" )
40- serverID = flag .String ("server_id" , "go_server" , "Server ID included in response" )
41- hostname = getHostname ()
46+ port = flag .Int ("port" , 8080 , "Listening port for test service" )
47+ maintenancePort = flag .Int ("maintenance_port" , 8081 , "Listening port for maintenance services like health, reflection, channelz etc when -secure_mode is true. When -secure_mode is false, all these services will be registered on -port" )
48+ serverID = flag .String ("server_id" , "go_server" , "Server ID included in response" )
49+ secureMode = flag .Bool ("secure_mode" , false , "If true, retrieve security configuration from the management server. Else, use insecure credentials." )
4250
4351 logger = grpclog .Component ("interop" )
4452)
@@ -51,28 +59,126 @@ func getHostname() string {
5159 return hostname
5260}
5361
54- type server struct {
62+ // testServiceImpl provides an implementation of the TestService defined in
63+ // grpc.testing package.
64+ type testServiceImpl struct {
5565 testgrpc.UnimplementedTestServiceServer
66+ hostname string
5667}
5768
58- func (s * server ) EmptyCall (ctx context.Context , _ * testpb.Empty ) (* testpb.Empty , error ) {
59- grpc .SetHeader (ctx , metadata .Pairs ("hostname" , hostname ))
69+ func (s * testServiceImpl ) EmptyCall (ctx context.Context , _ * testpb.Empty ) (* testpb.Empty , error ) {
70+ grpc .SetHeader (ctx , metadata .Pairs ("hostname" , s . hostname ))
6071 return & testpb.Empty {}, nil
6172}
6273
63- func (s * server ) UnaryCall (ctx context.Context , in * testpb.SimpleRequest ) (* testpb.SimpleResponse , error ) {
64- grpc .SetHeader (ctx , metadata .Pairs ("hostname" , hostname ))
65- return & testpb.SimpleResponse {ServerId : * serverID , Hostname : hostname }, nil
74+ func (s * testServiceImpl ) UnaryCall (ctx context.Context , in * testpb.SimpleRequest ) (* testpb.SimpleResponse , error ) {
75+ grpc .SetHeader (ctx , metadata .Pairs ("hostname" , s .hostname ))
76+ return & testpb.SimpleResponse {ServerId : * serverID , Hostname : s .hostname }, nil
77+ }
78+
79+ // xdsUpdateHealthServiceImpl provides an implementation of the
80+ // XdsUpdateHealthService defined in grpc.testing package.
81+ type xdsUpdateHealthServiceImpl struct {
82+ testgrpc.UnimplementedXdsUpdateHealthServiceServer
83+ healthServer * health.Server
84+ }
85+
86+ func (x * xdsUpdateHealthServiceImpl ) SetServing (_ context.Context , _ * testpb.Empty ) (* testpb.Empty , error ) {
87+ x .healthServer .SetServingStatus ("" , healthpb .HealthCheckResponse_SERVING )
88+ return & testpb.Empty {}, nil
89+
90+ }
91+
92+ func (x * xdsUpdateHealthServiceImpl ) SetNotServing (_ context.Context , _ * testpb.Empty ) (* testpb.Empty , error ) {
93+ x .healthServer .SetServingStatus ("" , healthpb .HealthCheckResponse_NOT_SERVING )
94+ return & testpb.Empty {}, nil
95+ }
96+
97+ func xdsServingModeCallback (addr net.Addr , args xds.ServingModeChangeArgs ) {
98+ logger .Infof ("Serving mode for xDS server at %s changed to %s" , addr .String (), args .Mode )
99+ if args .Err != nil {
100+ logger .Infof ("ServingModeCallback returned error: %v" , args .Err )
101+ }
66102}
67103
68104func main () {
69105 flag .Parse ()
70- p := strconv .Itoa (* port )
71- lis , err := net .Listen ("tcp" , ":" + p )
106+
107+ if * secureMode && * port == * maintenancePort {
108+ logger .Fatal ("-port and -maintenance_port must be different when -secure_mode is set" )
109+ }
110+
111+ testService := & testServiceImpl {hostname : getHostname ()}
112+ healthServer := health .NewServer ()
113+ updateHealthService := & xdsUpdateHealthServiceImpl {healthServer : healthServer }
114+
115+ // If -secure_mode is not set, expose all services on -port with a regular
116+ // gRPC server.
117+ if ! * secureMode {
118+ lis , err := net .Listen ("tcp4" , fmt .Sprintf (":%d" , * port ))
119+ if err != nil {
120+ logger .Fatalf ("net.Listen(%s) failed: %v" , fmt .Sprintf (":%d" , * port ), err )
121+ }
122+
123+ server := grpc .NewServer ()
124+ testgrpc .RegisterTestServiceServer (server , testService )
125+ healthServer .SetServingStatus ("" , healthpb .HealthCheckResponse_SERVING )
126+ healthpb .RegisterHealthServer (server , healthServer )
127+ testgrpc .RegisterXdsUpdateHealthServiceServer (server , updateHealthService )
128+ reflection .Register (server )
129+ cleanup , err := admin .Register (server )
130+ if err != nil {
131+ logger .Fatalf ("Failed to register admin services: %v" , err )
132+ }
133+ defer cleanup ()
134+ if err := server .Serve (lis ); err != nil {
135+ logger .Errorf ("Serve() failed: %v" , err )
136+ }
137+ return
138+ }
139+
140+ // Create a listener on -port to expose the test service.
141+ testLis , err := net .Listen ("tcp4" , fmt .Sprintf (":%d" , * port ))
72142 if err != nil {
73- logger .Fatalf ("failed to listen: %v" , err )
143+ logger .Fatalf ("net.Listen(%s) failed: %v" , fmt .Sprintf (":%d" , * port ), err )
144+ }
145+
146+ // Create server-side xDS credentials with a plaintext fallback.
147+ creds , err := xdscreds .NewServerCredentials (xdscreds.ServerOptions {FallbackCreds : insecure .NewCredentials ()})
148+ if err != nil {
149+ logger .Fatalf ("Failed to create xDS credentials: %v" , err )
150+ }
151+
152+ // Create an xDS enabled gRPC server, register the test service
153+ // implementation and start serving.
154+ testServer := xds .NewGRPCServer (grpc .Creds (creds ), xds .ServingModeCallback (xdsServingModeCallback ))
155+ testgrpc .RegisterTestServiceServer (testServer , testService )
156+ go func () {
157+ if err := testServer .Serve (testLis ); err != nil {
158+ logger .Errorf ("test server Serve() failed: %v" , err )
159+ }
160+ }()
161+ defer testServer .Stop ()
162+
163+ // Create a listener on -maintenance_port to expose other services.
164+ maintenanceLis , err := net .Listen ("tcp4" , fmt .Sprintf (":%d" , * maintenancePort ))
165+ if err != nil {
166+ logger .Fatalf ("net.Listen(%s) failed: %v" , fmt .Sprintf (":%d" , * maintenancePort ), err )
167+ }
168+
169+ // Create a regular gRPC server and register the maintenance services on
170+ // it and start serving.
171+ maintenanceServer := grpc .NewServer ()
172+ healthServer .SetServingStatus ("" , healthpb .HealthCheckResponse_SERVING )
173+ healthpb .RegisterHealthServer (maintenanceServer , healthServer )
174+ testgrpc .RegisterXdsUpdateHealthServiceServer (maintenanceServer , updateHealthService )
175+ reflection .Register (maintenanceServer )
176+ cleanup , err := admin .Register (maintenanceServer )
177+ if err != nil {
178+ logger .Fatalf ("Failed to register admin services: %v" , err )
179+ }
180+ defer cleanup ()
181+ if err := maintenanceServer .Serve (maintenanceLis ); err != nil {
182+ logger .Errorf ("maintenance server Serve() failed: %v" , err )
74183 }
75- s := grpc .NewServer ()
76- testgrpc .RegisterTestServiceServer (s , & server {})
77- s .Serve (lis )
78184}
0 commit comments