Example: Google Auth example with PubSub API ListTopics for a project ID (#5162)

* Working Google Auth example with PubSub API ListTopics for a project ID
Added another MD file for GOOGLE_AUTH_EXAMPLE
This commit is contained in:
sanjaypujare 2018-12-18 16:47:42 -08:00 committed by GitHub
parent 64000135cb
commit 847eae8d37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 475 additions and 0 deletions

View File

@ -27,6 +27,7 @@ before trying out the examples.
- [Authentication](AUTHENTICATION_EXAMPLE.md)
- [Google Authentication](example-gauth/GOOGLE_AUTH_EXAMPLE.md)
### To build the examples

View File

@ -13,4 +13,18 @@ local_repository(
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
maven_jar(
name = "com_google_api_grpc_cloud_pubsub_v1",
artifact = "com.google.api.grpc:grpc-google-cloud-pubsub-v1:0.1.24",
sha1 = "601d8be0fd0cc0e050b1af3b88f191ada9a2f4e5",
)
maven_jar(
name = "com_google_api_grpc_proto_cloud_pubsub_v1",
artifact = "com.google.api.grpc:proto-google-cloud-pubsub-v1:0.1.24",
sha1 = "e6dd66635f674b4e380dfd3de252ae019a51a67e",
)
grpc_java_repositories()

View File

@ -0,0 +1,27 @@
load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
java_library(
name = "example-gauth",
testonly = 1,
srcs = glob(
["src/main/java/**/*.java"],
),
deps = [
"@io_grpc_grpc_java//core",
"@io_grpc_grpc_java//protobuf",
"@io_grpc_grpc_java//stub",
"@io_grpc_grpc_java//auth",
"@com_google_auth_google_auth_library_oauth2_http//jar",
"@com_google_api_grpc_cloud_pubsub_v1//jar",
"@com_google_api_grpc_proto_cloud_pubsub_v1//jar",
],
)
java_binary(
name = "google-auth-client",
testonly = 1,
main_class = "io.grpc.examples.googleAuth.GoogleAuthClient",
runtime_deps = [
":example-gauth",
],
)

View File

@ -0,0 +1,106 @@
Google Authentication Example
==============================================
This example illustrates how to access [Google APIs](https://cloud.google.com/apis/docs/overview) via gRPC and
open source [Google API libraries](https://github.com/googleapis) using
[Google authentication](https://developers.google.com/identity/protocols/OAuth2), specifically the
[GoogleCredentials](https://github.com/googleapis/google-auth-library-java/blob/master/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java)
class.
The example requires grpc-java to be pre-built. Using a release tag will download the relevant binaries
from a maven repository. But if you need the latest SNAPSHOT binaries you will need to follow
[COMPILING](../COMPILING.md) to build these.
Please follow the [steps](./README.md#to-build-the-examples) to build the examples. The build creates
the script `google-auth-client` in the `build/install/examples/bin/` directory which can be
used to run this example.
The example uses [Google PubSub gRPC API](https://cloud.google.com/pubsub/docs/reference/rpc/) to get a list
of PubSub topics for a project. You will need to perform the following steps to get the example to work.
Wherever possible, the required UI links or `gcloud` shell commands are mentioned.
1. Create or use an existing [Google Cloud](https://cloud.google.com) account. In your account, you may need
to enable features to exercise this example and this may cost some money.
2. Use an existing project, or [create a project](https://pantheon.corp.google.com/projectcreate),
say `Google Auth Pubsub example`. Note down the project ID of this project - say `xyz123` for this example.
Use the project drop-down from the top or use the cloud shell command
```
gcloud projects list
```
to get the project ID.
3. Unless already enabled, [enable the Cloud Pub/Sub API for your project](https://console.developers.google.com/apis/api/pubsub.googleapis.com/overview)
by clicking `Enable`.
4. Go to the [GCP Pub/Sub console](https://pantheon.corp.google.com/cloudpubsub). Create a couple of new
topics using the "+ CREATE TOPIC" button, say `Topic1` and `Topic2`. You can also use the gcloud command
to create a topic:
```
gcloud pubsub topics create Topic1
```
5. You will now need to set up [authentication](https://cloud.google.com/docs/authentication/) and a
[service account](https://cloud.google.com/docs/authentication/#service_accounts) in order to access
Pub/Sub via gRPC APIs as described [here](https://cloud.google.com/iam/docs/creating-managing-service-accounts).
Assign the [role](https://cloud.google.com/iam/docs/granting-roles-to-service-accounts) `Project -> Owner`
and for Key type select JSON. Once you click `Create`, a JSON file containing your key is downloaded to
your computer. Note down the path of this file or copy this file to the computer and file system where
you will be running the example application as described later. Assume this JSON file is available at
`/path/to/JSON/file`. You can also use the `gcloud` shell commands to
[create the service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#iam-service-accounts-create-gcloud)
and [the JSON file](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-gcloud).
#### To build the examples
1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**
2. Run in this directory:
```
$ ../gradlew installDist
```
#### How to run the example:
`google-auth-client` requires two command line arguments for the location of the JSON file and the project ID:
```text
USAGE: GoogleAuthClient <path-to-JSON-file> <project-ID>
```
The first argument <path-to-JSON-file> is the location of the JSON file you created in step 5 above.
The second argument <project-ID> is the project ID in the form "projects/xyz123" where "xyz123" is
the project ID of the project you created (or used) in step 2 above.
```bash
# Run the client
./build/install/example-gauth/bin/google-auth-client /path/to/JSON/file projects/xyz123
```
That's it! The client will show the list of Pub/Sub topics for the project as follows:
```
INFO: Topics list:
[name: "projects/xyz123/topics/Topic1"
, name: "projects/xyz123/topics/Topic2"
]
```
## Maven
If you prefer to use Maven:
1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**
2. Run in this directory:
```
$ mvn verify
$ # Run the client
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.googleAuth.GoogleAuthClient -Dexec.args="/path/to/JSON/file projects/xyz123"
```
## Bazel
If you prefer to use Bazel:
```
(With Bazel v0.8.0 or above.)
$ bazel build :google-auth-client
$ # Run the client
$ ../bazel-bin/google-auth-client /path/to/JSON/file projects/xyz123
```

View File

@ -0,0 +1,72 @@
plugins {
// Provide convenience executables for trying out the examples.
id 'application'
// ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier gradle versions
id 'com.google.protobuf' version '0.8.5'
// Generate IntelliJ IDEA's .idea & .iml project files
id 'idea'
}
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/repos/central/data/"
}
mavenLocal()
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
// IMPORTANT: You probably want the non-SNAPSHOT version of gRPC. Make sure you
// are looking at a tagged version of the example and not "master"!
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
def grpcVersion = '1.18.0-SNAPSHOT' // CURRENT_GRPC_VERSION
def protobufVersion = '3.5.1'
def protocVersion = '3.5.1-1'
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
implementation "io.grpc:grpc-auth:${grpcVersion}"
compileOnly "javax.annotation:javax.annotation-api:1.2"
implementation "com.google.auth:google-auth-library-oauth2-http:0.9.0"
implementation "com.google.api.grpc:grpc-google-cloud-pubsub-v1:0.1.24"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
}
generateProtoTasks {
all()*.plugins { grpc {} }
}
}
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
startScripts.enabled = false
task googleAuthClient(type: CreateStartScripts) {
mainClassName = 'io.grpc.examples.googleAuth.GoogleAuthClient'
applicationName = 'google-auth-client'
outputDir = new File(project.buildDir, 'tmp')
classpath = startScripts.classpath
}
applicationDistribution.into('bin') {
from(googleAuthClient)
fileMode = 0755
}

View File

@ -0,0 +1,113 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.grpc</groupId>
<artifactId>example-gauth</artifactId>
<packaging>jar</packaging>
<!-- Feel free to delete the comment at the end of these lines. It is just
for safely updating the version in our release process. -->
<version>1.18.0-SNAPSHOT</version><!-- CURRENT_GRPC_VERSION -->
<name>example-gauth</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.18.0-SNAPSHOT</grpc.version><!-- CURRENT_GRPC_VERSION -->
<protoc.version>3.5.1-1</protoc.version>
<protobuf.version>3.5.1</protobuf.version>
<netty.tcnative.version>2.0.20.Final</netty.tcnative.version>
<!-- required for jdk9 -->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-auth</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
<scope>provided</scope> <!-- not needed at runtime -->
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<version>${grpc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.google.api.grpc</groupId>
<artifactId>grpc-google-cloud-pubsub-v1</artifactId>
<version>0.1.24</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,8 @@
pluginManagement {
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/repos/central/data/"
}
gradlePluginPortal()
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.examples.googleAuth;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.pubsub.v1.ListTopicsRequest;
import com.google.pubsub.v1.ListTopicsResponse;
import com.google.pubsub.v1.PublisherGrpc;
import io.grpc.CallCredentials;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.auth.MoreCallCredentials;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Example to illustrate use of Google credentials as described in
* @see <a href="../../../../../../GOOGLE_AUTH_EXAMPLE.md">Google Auth Example README</a>
*
* Also @see <a href="https://cloud.google.com/pubsub/docs/reference/rpc/">Google Cloud Pubsub via gRPC</a>
*/
public class GoogleAuthClient {
private static final Logger logger = Logger.getLogger(GoogleAuthClient.class.getName());
private final ManagedChannel channel;
/**
* stub generated from the proto file.
*/
private final PublisherGrpc.PublisherBlockingStub blockingStub;
/**
* Construct our gRPC client that connects to the pubsub server at {@code host:port}.
*
* @param host host to connect to - typically "pubsub.googleapis.com"
* @param port port to connect to - typically 443 - the TLS port
* @param callCredentials the Google call credentials created from a JSON file
*/
public GoogleAuthClient(String host, int port, CallCredentials callCredentials) {
// Google API invocation requires a secure channel. Channels are secure by default (SSL/TLS)
this(ManagedChannelBuilder.forAddress(host, port).build(), callCredentials);
}
/**
* Construct our gRPC client that connects to the pubsub server using an existing channel.
*
* @param channel channel that has been built already
* @param callCredentials the Google call credentials created from a JSON file
*/
GoogleAuthClient(ManagedChannel channel, CallCredentials callCredentials) {
this.channel = channel;
blockingStub = PublisherGrpc.newBlockingStub(channel).withCallCredentials(callCredentials);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/**
* Get topics (max 10) for our project ID: the topic list is logged to the logger.
*
* @param projectID the GCP project ID to get the pubsub topics for. This is a string like
* "projects/balmy-cirrus-225307" where "balmy-cirrus-225307" is
* the project ID for the project you created.
*/
public void getTopics(String projectID) {
logger.log(Level.INFO, "Will try to get topics for project {0} ...", projectID);
ListTopicsRequest request = ListTopicsRequest.newBuilder()
.setPageSize(10) // get max 10 topics
.setProject(projectID) // for our projectID
.build();
ListTopicsResponse response;
try {
response = blockingStub.listTopics(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.log(Level.INFO, "Topics list:\n {0}", response.getTopicsList());
}
/**
* The app requires 2 arguments as described in
* @see <a href="../../../../../../GOOGLE_AUTH_EXAMPLE.md">Google Auth Example README</a>
*
* arg0 = location of the JSON file for the service account you created in the GCP console
* arg1 = project name in the form "projects/balmy-cirrus-225307" where "balmy-cirrus-225307" is
* the project ID for the project you created.
*
*/
public static void main(String[] args) throws Exception {
if (args.length < 2) {
logger.severe("Usage: please pass 2 arguments:\n" +
"arg0 = location of the JSON file for the service account you created in the GCP console\n" +
"arg1 = project name in the form \"projects/xyz\" where \"xyz\" is the project ID of the project you created.\n");
System.exit(1);
}
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(args[0]));
// We need to create appropriate scope as per https://cloud.google.com/storage/docs/authentication#oauth-scopes
credentials = credentials.createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
// credentials must be refreshed before the access token is available
credentials.refreshAccessToken();
GoogleAuthClient client =
new GoogleAuthClient("pubsub.googleapis.com", 443, MoreCallCredentials.from(credentials));
try {
client.getTopics(args[1]);
} finally {
client.shutdown();
}
}
}