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.ManagedChannel; 20 import io.grpc.StatusRuntimeException; 21 import io.grpc.examples.helloworld.GreeterGrpc; 22 import io.grpc.examples.helloworld.HelloReply; 23 import io.grpc.examples.helloworld.HelloRequest; 24 import io.grpc.examples.helloworld.HelloWorldServer; 25 import io.grpc.netty.GrpcSslContexts; 26 import io.grpc.netty.NegotiationType; 27 import io.grpc.netty.NettyChannelBuilder; 28 import io.netty.handler.ssl.SslContext; 29 import io.netty.handler.ssl.SslContextBuilder; 30 31 import javax.net.ssl.SSLException; 32 import java.io.File; 33 import java.util.concurrent.TimeUnit; 34 import java.util.logging.Level; 35 import java.util.logging.Logger; 36 37 /** 38 * A simple client that requests a greeting from the {@link HelloWorldServer} with TLS. 39 */ 40 public class HelloWorldClientTls { 41 private static final Logger logger = Logger.getLogger(HelloWorldClientTls.class.getName()); 42 43 private final ManagedChannel channel; 44 private final GreeterGrpc.GreeterBlockingStub blockingStub; 45 buildSslContext(String trustCertCollectionFilePath, String clientCertChainFilePath, String clientPrivateKeyFilePath)46 private static SslContext buildSslContext(String trustCertCollectionFilePath, 47 String clientCertChainFilePath, 48 String clientPrivateKeyFilePath) throws SSLException { 49 SslContextBuilder builder = GrpcSslContexts.forClient(); 50 if (trustCertCollectionFilePath != null) { 51 builder.trustManager(new File(trustCertCollectionFilePath)); 52 } 53 if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) { 54 builder.keyManager(new File(clientCertChainFilePath), new File(clientPrivateKeyFilePath)); 55 } 56 return builder.build(); 57 } 58 59 /** 60 * Construct client connecting to HelloWorld server at {@code host:port}. 61 */ HelloWorldClientTls(String host, int port, SslContext sslContext)62 public HelloWorldClientTls(String host, 63 int port, 64 SslContext sslContext) throws SSLException { 65 66 this(NettyChannelBuilder.forAddress(host, port) 67 .negotiationType(NegotiationType.TLS) 68 .sslContext(sslContext) 69 .build()); 70 } 71 72 /** 73 * Construct client for accessing RouteGuide server using the existing channel. 74 */ HelloWorldClientTls(ManagedChannel channel)75 HelloWorldClientTls(ManagedChannel channel) { 76 this.channel = channel; 77 blockingStub = GreeterGrpc.newBlockingStub(channel); 78 } 79 shutdown()80 public void shutdown() throws InterruptedException { 81 channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); 82 } 83 84 /** 85 * Say hello to server. 86 */ greet(String name)87 public void greet(String name) { 88 logger.info("Will try to greet " + name + " ..."); 89 HelloRequest request = HelloRequest.newBuilder().setName(name).build(); 90 HelloReply response; 91 try { 92 response = blockingStub.sayHello(request); 93 } catch (StatusRuntimeException e) { 94 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); 95 return; 96 } 97 logger.info("Greeting: " + response.getMessage()); 98 } 99 100 /** 101 * Greet server. If provided, the first element of {@code args} is the name to use in the 102 * greeting. 103 */ main(String[] args)104 public static void main(String[] args) throws Exception { 105 106 if (args.length < 2 || args.length == 4 || args.length > 5) { 107 System.out.println("USAGE: HelloWorldClientTls host port [trustCertCollectionFilePath] " + 108 "[clientCertChainFilePath] [clientPrivateKeyFilePath]\n Note: clientCertChainFilePath and " + 109 "clientPrivateKeyFilePath are only needed if mutual auth is desired. And if you specify " + 110 "clientCertChainFilePath you must also specify clientPrivateKeyFilePath"); 111 System.exit(0); 112 } 113 114 HelloWorldClientTls client; 115 switch (args.length) { 116 case 2: 117 client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]), 118 buildSslContext(null, null, null)); 119 break; 120 case 3: 121 client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]), 122 buildSslContext(args[2], null, null)); 123 break; 124 default: 125 client = new HelloWorldClientTls(args[0], Integer.parseInt(args[1]), 126 buildSslContext(args[2], args[3], args[4])); 127 } 128 129 try { 130 /* Access a service running on the local machine on port 50051 */ 131 String user = "world"; 132 if (args.length > 0) { 133 user = args[0]; /* Use the arg as the name to greet if provided */ 134 } 135 client.greet(user); 136 } finally { 137 client.shutdown(); 138 } 139 } 140 } 141