1 /* 2 * Copyright 2023 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.debug; 18 19 import io.grpc.Grpc; 20 import io.grpc.InsecureServerCredentials; 21 import io.grpc.Server; 22 import io.grpc.ServerBuilder; 23 import io.grpc.health.v1.HealthCheckResponse.ServingStatus; 24 import io.grpc.protobuf.services.ProtoReflectionService; 25 import io.grpc.services.AdminInterface; 26 import io.grpc.services.HealthStatusManager; 27 import java.io.IOException; 28 import java.util.concurrent.TimeUnit; 29 30 /** 31 * A server that hosts HostnameGreeter, plus the channelz service which grpcdebug uses. 32 */ 33 public final class HostnameDebuggableServer { 34 static int port = 50051; 35 static String hostname = null; 36 main(String[] args)37 public static void main(String[] args) throws IOException, InterruptedException { 38 parseArgs(args); // sets port and hostname 39 40 final Server server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create()) 41 .addService(new HostnameGreeter(hostname)) 42 .addServices(AdminInterface.getStandardServices()) // the key add for enabling grpcdebug 43 .build() 44 .start(); 45 46 System.out.println("Listening on port " + port); 47 48 addShutdownHook(server); // Configures cleanup 49 server.awaitTermination(); // Block until shutdown 50 } 51 parseArgs(String[] args)52 private static void parseArgs(String[] args) { 53 if (args.length >= 1) { 54 try { 55 port = Integer.parseInt(args[0]); 56 } catch (NumberFormatException ex) { 57 System.err.println("Usage: [port [hostname]]"); 58 System.err.println(""); 59 System.err.println(" port The listen port. Defaults to " + port); 60 System.err.println(" hostname The name clients will see in greet responses. "); 61 System.err.println(" Defaults to the machine's hostname"); 62 System.exit(1); 63 } 64 } 65 if (args.length >= 2) { 66 hostname = args[1]; 67 } 68 } 69 addShutdownHook(final Server server)70 private static void addShutdownHook(final Server server) { 71 Runtime.getRuntime().addShutdownHook(new Thread() { 72 @Override 73 public void run() { 74 // Start graceful shutdown 75 server.shutdown(); 76 try { 77 // Wait for RPCs to complete processing 78 if (!server.awaitTermination(30, TimeUnit.SECONDS)) { 79 // That was plenty of time. Let's cancel the remaining RPCs 80 server.shutdownNow(); 81 // shutdownNow isn't instantaneous, so give a bit of time to clean resources up 82 // gracefully. Normally this will be well under a second. 83 server.awaitTermination(5, TimeUnit.SECONDS); 84 } 85 } catch (InterruptedException ex) { 86 server.shutdownNow(); 87 } 88 } 89 }); 90 } 91 } 92