• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.testing.integration;
18 
19 import com.google.common.annotations.VisibleForTesting;
20 import com.google.common.util.concurrent.MoreExecutors;
21 import io.grpc.Server;
22 import io.grpc.ServerInterceptors;
23 import io.grpc.alts.AltsServerBuilder;
24 import io.grpc.internal.testing.TestUtils;
25 import io.grpc.netty.GrpcSslContexts;
26 import io.grpc.netty.NettyServerBuilder;
27 import io.netty.handler.ssl.SslContext;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.ScheduledExecutorService;
30 import java.util.concurrent.TimeUnit;
31 
32 /** Server that manages startup/shutdown of a single {@code TestService}. */
33 public class TestServiceServer {
34   /** The main application allowing this server to be launched from the command line. */
main(String[] args)35   public static void main(String[] args) throws Exception {
36     // Let Netty use Conscrypt if it is available.
37     TestUtils.installConscryptIfAvailable();
38     final TestServiceServer server = new TestServiceServer();
39     server.parseArgs(args);
40     if (server.useTls) {
41       System.out.println(
42           "\nUsing fake CA for TLS certificate. Test clients should expect host\n"
43               + "*.test.google.fr and our test CA. For the Java test client binary, use:\n"
44               + "--server_host_override=foo.test.google.fr --use_test_ca=true\n");
45     }
46 
47     Runtime.getRuntime()
48         .addShutdownHook(
49             new Thread() {
50               @Override
51               public void run() {
52                 try {
53                   System.out.println("Shutting down");
54                   server.stop();
55                 } catch (Exception e) {
56                   e.printStackTrace();
57                 }
58               }
59             });
60     server.start();
61     System.out.println("Server started on port " + server.port);
62     server.blockUntilShutdown();
63   }
64 
65   private int port = 8080;
66   private boolean useTls = true;
67   private boolean useAlts = false;
68 
69   private ScheduledExecutorService executor;
70   private Server server;
71 
72   @VisibleForTesting
parseArgs(String[] args)73   void parseArgs(String[] args) {
74     boolean usage = false;
75     for (String arg : args) {
76       if (!arg.startsWith("--")) {
77         System.err.println("All arguments must start with '--': " + arg);
78         usage = true;
79         break;
80       }
81       String[] parts = arg.substring(2).split("=", 2);
82       String key = parts[0];
83       if ("help".equals(key)) {
84         usage = true;
85         break;
86       }
87       if (parts.length != 2) {
88         System.err.println("All arguments must be of the form --arg=value");
89         usage = true;
90         break;
91       }
92       String value = parts[1];
93       if ("port".equals(key)) {
94         port = Integer.parseInt(value);
95       } else if ("use_tls".equals(key)) {
96         useTls = Boolean.parseBoolean(value);
97       } else if ("use_alts".equals(key)) {
98         useAlts = Boolean.parseBoolean(value);
99       } else if ("grpc_version".equals(key)) {
100         if (!"2".equals(value)) {
101           System.err.println("Only grpc version 2 is supported");
102           usage = true;
103           break;
104         }
105       } else {
106         System.err.println("Unknown argument: " + key);
107         usage = true;
108         break;
109       }
110     }
111     if (useAlts) {
112       useTls = false;
113     }
114     if (usage) {
115       TestServiceServer s = new TestServiceServer();
116       System.out.println(
117           "Usage: [ARGS...]"
118               + "\n"
119               + "\n  --port=PORT           Port to connect to. Default " + s.port
120               + "\n  --use_tls=true|false  Whether to use TLS. Default " + s.useTls
121               + "\n  --use_alts=true|false Whether to use ALTS. Enable ALTS will disable TLS."
122               + "\n                        Default " + s.useAlts
123       );
124       System.exit(1);
125     }
126   }
127 
128   @VisibleForTesting
start()129   void start() throws Exception {
130     executor = Executors.newSingleThreadScheduledExecutor();
131     SslContext sslContext = null;
132     if (useAlts) {
133       server =
134           AltsServerBuilder.forPort(port)
135               .addService(
136                   ServerInterceptors.intercept(
137                       new TestServiceImpl(executor), TestServiceImpl.interceptors()))
138               .build()
139               .start();
140     } else {
141       if (useTls) {
142         sslContext =
143             GrpcSslContexts.forServer(
144                     TestUtils.loadCert("server1.pem"), TestUtils.loadCert("server1.key"))
145                 .build();
146       }
147       server =
148           NettyServerBuilder.forPort(port)
149               .sslContext(sslContext)
150               .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
151               .addService(
152                   ServerInterceptors.intercept(
153                       new TestServiceImpl(executor), TestServiceImpl.interceptors()))
154               .build()
155               .start();
156     }
157   }
158 
159   @VisibleForTesting
stop()160   void stop() throws Exception {
161     server.shutdownNow();
162     if (!server.awaitTermination(5, TimeUnit.SECONDS)) {
163       System.err.println("Timed out waiting for server shutdown");
164     }
165     MoreExecutors.shutdownAndAwaitTermination(executor, 5, TimeUnit.SECONDS);
166   }
167 
168   @VisibleForTesting
getPort()169   int getPort() {
170     return server.getPort();
171   }
172 
173   /** Await termination on the main thread since the grpc library uses daemon threads. */
blockUntilShutdown()174   private void blockUntilShutdown() throws InterruptedException {
175     if (server != null) {
176       server.awaitTermination();
177     }
178   }
179 }
180