1 /* 2 * Copyright 2018 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.googleAuth; 18 19 import com.google.auth.oauth2.GoogleCredentials; 20 import com.google.pubsub.v1.ListTopicsRequest; 21 import com.google.pubsub.v1.ListTopicsResponse; 22 import com.google.pubsub.v1.PublisherGrpc; 23 import io.grpc.CallCredentials; 24 import io.grpc.ManagedChannel; 25 import io.grpc.ManagedChannelBuilder; 26 import io.grpc.StatusRuntimeException; 27 import io.grpc.auth.MoreCallCredentials; 28 import java.io.FileInputStream; 29 import java.util.Arrays; 30 import java.util.concurrent.TimeUnit; 31 import java.util.logging.Level; 32 import java.util.logging.Logger; 33 34 /** 35 * Example to illustrate use of Google credentials as described in 36 * @see <a href="../../../../../../GOOGLE_AUTH_EXAMPLE.md">Google Auth Example README</a> 37 * 38 * Also @see <a href="https://cloud.google.com/pubsub/docs/reference/rpc/">Google Cloud Pubsub via gRPC</a> 39 */ 40 public class GoogleAuthClient { 41 private static final Logger logger = Logger.getLogger(GoogleAuthClient.class.getName()); 42 43 private final ManagedChannel channel; 44 45 /** 46 * stub generated from the proto file. 47 */ 48 private final PublisherGrpc.PublisherBlockingStub blockingStub; 49 50 /** 51 * Construct our gRPC client that connects to the pubsub server at {@code host:port}. 52 * 53 * @param host host to connect to - typically "pubsub.googleapis.com" 54 * @param port port to connect to - typically 443 - the TLS port 55 * @param callCredentials the Google call credentials created from a JSON file 56 */ GoogleAuthClient(String host, int port, CallCredentials callCredentials)57 public GoogleAuthClient(String host, int port, CallCredentials callCredentials) { 58 // Google API invocation requires a secure channel. Channels are secure by default (SSL/TLS) 59 this(ManagedChannelBuilder.forAddress(host, port).build(), callCredentials); 60 } 61 62 /** 63 * Construct our gRPC client that connects to the pubsub server using an existing channel. 64 * 65 * @param channel channel that has been built already 66 * @param callCredentials the Google call credentials created from a JSON file 67 */ GoogleAuthClient(ManagedChannel channel, CallCredentials callCredentials)68 GoogleAuthClient(ManagedChannel channel, CallCredentials callCredentials) { 69 this.channel = channel; 70 blockingStub = PublisherGrpc.newBlockingStub(channel).withCallCredentials(callCredentials); 71 } 72 shutdown()73 public void shutdown() throws InterruptedException { 74 channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); 75 } 76 77 /** 78 * Get topics (max 10) for our project ID: the topic list is logged to the logger. 79 * 80 * @param projectID the GCP project ID to get the pubsub topics for. This is a string like 81 * "projects/balmy-cirrus-225307" where "balmy-cirrus-225307" is 82 * the project ID for the project you created. 83 */ getTopics(String projectID)84 public void getTopics(String projectID) { 85 logger.log(Level.INFO, "Will try to get topics for project {0} ...", projectID); 86 87 ListTopicsRequest request = ListTopicsRequest.newBuilder() 88 .setPageSize(10) // get max 10 topics 89 .setProject(projectID) // for our projectID 90 .build(); 91 92 ListTopicsResponse response; 93 try { 94 response = blockingStub.listTopics(request); 95 } catch (StatusRuntimeException e) { 96 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); 97 return; 98 } 99 logger.log(Level.INFO, "Topics list:\n {0}", response.getTopicsList()); 100 } 101 102 /** 103 * The app requires 2 arguments as described in 104 * @see <a href="../../../../../../GOOGLE_AUTH_EXAMPLE.md">Google Auth Example README</a> 105 * 106 * arg0 = location of the JSON file for the service account you created in the GCP console 107 * arg1 = project name in the form "projects/balmy-cirrus-225307" where "balmy-cirrus-225307" is 108 * the project ID for the project you created. 109 * 110 */ main(String[] args)111 public static void main(String[] args) throws Exception { 112 if (args.length < 2) { 113 logger.severe("Usage: please pass 2 arguments:\n" + 114 "arg0 = location of the JSON file for the service account you created in the GCP console\n" + 115 "arg1 = project name in the form \"projects/xyz\" where \"xyz\" is the project ID of the project you created.\n"); 116 System.exit(1); 117 } 118 GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(args[0])); 119 120 // We need to create appropriate scope as per https://cloud.google.com/storage/docs/authentication#oauth-scopes 121 credentials = credentials.createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform")); 122 123 // credentials must be refreshed before the access token is available 124 credentials.refreshAccessToken(); 125 GoogleAuthClient client = 126 new GoogleAuthClient("pubsub.googleapis.com", 443, MoreCallCredentials.from(credentials)); 127 128 try { 129 client.getTopics(args[1]); 130 } finally { 131 client.shutdown(); 132 } 133 } 134 } 135