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.Grpc; 20 import io.grpc.Server; 21 import io.grpc.ServerCredentials; 22 import io.grpc.TlsServerCredentials; 23 import io.grpc.examples.helloworld.GreeterGrpc; 24 import io.grpc.examples.helloworld.HelloReply; 25 import io.grpc.examples.helloworld.HelloRequest; 26 import io.grpc.stub.StreamObserver; 27 import java.io.File; 28 import java.io.IOException; 29 import java.util.logging.Logger; 30 31 /** 32 * Server that manages startup/shutdown of a {@code Greeter} server with TLS enabled. 33 */ 34 public class HelloWorldServerTls { 35 private static final Logger logger = Logger.getLogger(HelloWorldServerTls.class.getName()); 36 37 private Server server; 38 39 private final int port; 40 private final ServerCredentials creds; 41 HelloWorldServerTls(int port, ServerCredentials creds)42 public HelloWorldServerTls(int port, ServerCredentials creds) { 43 this.port = port; 44 this.creds = creds; 45 } 46 start()47 private void start() throws IOException { 48 server = Grpc.newServerBuilderForPort(port, creds) 49 .addService(new GreeterImpl()) 50 .build() 51 .start(); 52 logger.info("Server started, listening on " + port); 53 Runtime.getRuntime().addShutdownHook(new Thread() { 54 @Override 55 public void run() { 56 // Use stderr here since the logger may have been reset by its JVM shutdown hook. 57 System.err.println("*** shutting down gRPC server since JVM is shutting down"); 58 HelloWorldServerTls.this.stop(); 59 System.err.println("*** server shut down"); 60 } 61 }); 62 } 63 stop()64 private void stop() { 65 if (server != null) { 66 server.shutdown(); 67 } 68 } 69 70 /** 71 * Await termination on the main thread since the grpc library uses daemon threads. 72 */ blockUntilShutdown()73 private void blockUntilShutdown() throws InterruptedException { 74 if (server != null) { 75 server.awaitTermination(); 76 } 77 } 78 79 /** 80 * Main launches the server from the command line. 81 */ main(String[] args)82 public static void main(String[] args) throws IOException, InterruptedException { 83 84 if (args.length < 3 || args.length > 4) { 85 System.out.println( 86 "USAGE: HelloWorldServerTls port certChainFilePath privateKeyFilePath " + 87 "[trustCertCollectionFilePath]\n Note: You only need to supply trustCertCollectionFilePath if you want " + 88 "to enable Mutual TLS."); 89 System.exit(0); 90 } 91 92 // If only providing a private key, you can use TlsServerCredentials.create() instead of 93 // interacting with the Builder. 94 TlsServerCredentials.Builder tlsBuilder = TlsServerCredentials.newBuilder() 95 .keyManager(new File(args[1]), new File(args[2])); 96 if (args.length == 4) { 97 tlsBuilder.trustManager(new File(args[3])); 98 tlsBuilder.clientAuth(TlsServerCredentials.ClientAuth.REQUIRE); 99 } 100 final HelloWorldServerTls server = new HelloWorldServerTls( 101 Integer.parseInt(args[0]), tlsBuilder.build()); 102 server.start(); 103 server.blockUntilShutdown(); 104 } 105 106 static class GreeterImpl extends GreeterGrpc.GreeterImplBase { 107 108 @Override sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver)109 public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { 110 HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); 111 responseObserver.onNext(reply); 112 responseObserver.onCompleted(); 113 } 114 } 115 } 116