• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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.examples.helloworldtls;
18 
19 import io.grpc.Server;
20 import io.grpc.examples.helloworld.GreeterGrpc;
21 import io.grpc.examples.helloworld.HelloReply;
22 import io.grpc.examples.helloworld.HelloRequest;
23 import io.grpc.netty.GrpcSslContexts;
24 import io.grpc.netty.NettyServerBuilder;
25 import io.grpc.stub.StreamObserver;
26 import io.netty.handler.ssl.ClientAuth;
27 import io.netty.handler.ssl.SslContextBuilder;
28 import io.netty.handler.ssl.SslProvider;
29 
30 import java.io.File;
31 import java.io.IOException;
32 import java.net.InetSocketAddress;
33 import java.util.logging.Logger;
34 
35 /**
36  * Server that manages startup/shutdown of a {@code Greeter} server with TLS enabled.
37  */
38 public class HelloWorldServerTls {
39     private static final Logger logger = Logger.getLogger(HelloWorldServerTls.class.getName());
40 
41     private Server server;
42 
43     private final String host;
44     private final int port;
45     private final String certChainFilePath;
46     private final String privateKeyFilePath;
47     private final String trustCertCollectionFilePath;
48 
HelloWorldServerTls(String host, int port, String certChainFilePath, String privateKeyFilePath, String trustCertCollectionFilePath)49     public HelloWorldServerTls(String host,
50                                int port,
51                                String certChainFilePath,
52                                String privateKeyFilePath,
53                                String trustCertCollectionFilePath) {
54         this.host = host;
55         this.port = port;
56         this.certChainFilePath = certChainFilePath;
57         this.privateKeyFilePath = privateKeyFilePath;
58         this.trustCertCollectionFilePath = trustCertCollectionFilePath;
59     }
60 
getSslContextBuilder()61     private SslContextBuilder getSslContextBuilder() {
62         SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(new File(certChainFilePath),
63                 new File(privateKeyFilePath));
64         if (trustCertCollectionFilePath != null) {
65             sslClientContextBuilder.trustManager(new File(trustCertCollectionFilePath));
66             sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
67         }
68         return GrpcSslContexts.configure(sslClientContextBuilder,
69                 SslProvider.OPENSSL);
70     }
71 
start()72     private void start() throws IOException {
73         server = NettyServerBuilder.forAddress(new InetSocketAddress(host, port))
74                 .addService(new GreeterImpl())
75                 .sslContext(getSslContextBuilder().build())
76                 .build()
77                 .start();
78         logger.info("Server started, listening on " + port);
79         Runtime.getRuntime().addShutdownHook(new Thread() {
80             @Override
81             public void run() {
82                 // Use stderr here since the logger may have been reset by its JVM shutdown hook.
83                 System.err.println("*** shutting down gRPC server since JVM is shutting down");
84                 HelloWorldServerTls.this.stop();
85                 System.err.println("*** server shut down");
86             }
87         });
88     }
89 
stop()90     private void stop() {
91         if (server != null) {
92             server.shutdown();
93         }
94     }
95 
96     /**
97      * Await termination on the main thread since the grpc library uses daemon threads.
98      */
blockUntilShutdown()99     private void blockUntilShutdown() throws InterruptedException {
100         if (server != null) {
101             server.awaitTermination();
102         }
103     }
104 
105     /**
106      * Main launches the server from the command line.
107      */
main(String[] args)108     public static void main(String[] args) throws IOException, InterruptedException {
109 
110         if (args.length < 4 || args.length > 5) {
111             System.out.println(
112                     "USAGE: HelloWorldServerTls host port certChainFilePath privateKeyFilePath " +
113                     "[trustCertCollectionFilePath]\n  Note: You only need to supply trustCertCollectionFilePath if you want " +
114                     "to enable Mutual TLS.");
115             System.exit(0);
116         }
117 
118         final HelloWorldServerTls server = new HelloWorldServerTls(args[0],
119                 Integer.parseInt(args[1]),
120                 args[2],
121                 args[3],
122                 args.length == 5 ? args[4] : null);
123         server.start();
124         server.blockUntilShutdown();
125     }
126 
127     static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
128 
129         @Override
sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver)130         public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
131             HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
132             responseObserver.onNext(reply);
133             responseObserver.onCompleted();
134         }
135     }
136 }
137