diff --git a/generation/consolidate_config.sh b/generation/consolidate_config.sh
index 7faa2d7393b8..7ce298bc110a 100755
--- a/generation/consolidate_config.sh
+++ b/generation/consolidate_config.sh
@@ -9,7 +9,7 @@ set -e
function runRegexOnPoms {
perl_command=$1
search=$2
- for pomFile in $(find . -mindepth 2 -maxdepth 3 -name pom.xml | sort ); do
+ for pomFile in $(find . -mindepth 2 -maxdepth 3 -name pom.xml |sort --dictionary-order); do
if [[ $pomFile =~ .*google-cloud-jar-parent.* ]]; then
continue
fi
diff --git a/generation/generate_release_please_config.sh b/generation/generate_release_please_config.sh
index 0a24eab53005..2ef449a1ed83 100755
--- a/generation/generate_release_please_config.sh
+++ b/generation/generate_release_please_config.sh
@@ -14,9 +14,10 @@ release_please_config_file="release-please-config.json"
echo "{" > "${release_please_manifest_file}"
-num_modules=$(find . -mindepth 2 -maxdepth 2 -name pom.xml | wc -l)
+module_list=$(find . -mindepth 2 -maxdepth 2 -name pom.xml | sort --dictionary-order |xargs dirname)
+num_modules=$(echo "${module_list}"| wc -l)
num_modules=$((num_modules))
-for path in $(find . -mindepth 2 -maxdepth 2 -name pom.xml | sort --dictionary-order | xargs dirname); do
+for path in $module_list; do
# path starts with ./{module}, we need to exclude the first two chars
module_name="${path:2}"
diff --git a/google-cloud-examples/README.md b/google-cloud-examples/README.md
new file mode 100644
index 000000000000..48b1528acccc
--- /dev/null
+++ b/google-cloud-examples/README.md
@@ -0,0 +1,185 @@
+Google Cloud Java Client Examples
+=================================
+
+Examples for google-cloud (Java idiomatic client for [Google Cloud Platform][cloud-platform] services).
+
+**Note about migration**: In September 2022, this folder was moved from [main_202208 branch](
+https://github.com/googleapis/google-cloud-java/tree/main_202208/google-cloud-examples)
+to this branch. The `pom.xml` file has been removed as we no longer build the directory.
+The old branch has pom.xml to build the project.
+
+[![CircleCI](https://circleci.com/gh/googleapis/google-cloud-java/tree/master.svg?style=shield)](https://circleci.com/gh/googleapis/google-cloud-java/tree/master)
+[![Coverage Status](https://coveralls.io/repos/googleapis/google-cloud-java/badge.svg?branch=master)](https://coveralls.io/r/googleapis/google-cloud-java?branch=master)
+[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-examples.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-examples.svg)
+[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/google-cloud-java)
+[![Dependency Status](https://www.versioneye.com/user/projects/58fe4c8d6ac171426c414772/badge.svg?style=flat)](https://www.versioneye.com/user/projects/58fe4c8d6ac171426c414772)
+
+- [Examples](https://googleapis.dev/java/google-cloud-clients/latest/index.html?com/google/cloud/examples/package-summary.html)
+
+Quickstart
+----------
+
+[//]: # ({x-version-update-start:google-cloud-examples:released})
+If you are using Maven, add this to your pom.xml file
+```xml
+
+ com.google.cloud
+ google-cloud-examples
+ 0.120.0-alpha
+
+```
+If you are using Gradle, add this to your dependencies
+```Groovy
+compile 'com.google.cloud:google-cloud-examples:0.120.0-alpha'
+```
+If you are using SBT, add this to your dependencies
+```Scala
+libraryDependencies += "com.google.cloud" % "google-cloud-examples" % "0.120.0-alpha"
+```
+[//]: # ({x-version-update-end})
+
+To run examples from your command line:
+
+1. Log in using gcloud SDK (`gcloud auth login` in command line)
+
+2. Set your current project using `gcloud config set project PROJECT_ID`. This step is not necessary for `ResourceManagerExample`.
+
+3. Compile using Maven: `mvn install -DskipTests` in command line from your base project directory
+ then `cd google-cloud-examples` and finally `mvn package appassembler:assemble -DskipTests`.
+
+4. Run an example from the command line using the Maven-generated scripts.
+
+ * Here's an example run of `ComputeExample`.
+
+ Before running the example, go to the [Google Developers Console][developers-console] to ensure
+ that Compute API is enabled.
+ ```
+ target/appassembler/bin/ComputeExample create image-disk us-central1-a test-disk debian-cloud debian-8-jessie-v20160329
+ target/appassembler/bin/ComputeExample create instance us-central1-a test-instance n1-standard-1 test-disk default
+ target/appassembler/bin/ComputeExample add-access-config us-central1-a test-instance nic0 NAT
+ target/appassembler/bin/ComputeExample delete instance us-central1-a test-instance
+ target/appassembler/bin/ComputeExample delete disk us-central1-a test-disk
+ ```
+
+ * Here's an example run of `DatastoreExample`.
+
+ Be sure to change the placeholder project ID "your-project-id" with your own project ID. Also note that you have to enable the Google Cloud Datastore API on the [Google Developers Console][developers-console] before running the following commands.
+ ```
+ target/appassembler/bin/DatastoreExample your-project-id my_name add my\ comment
+ target/appassembler/bin/DatastoreExample your-project-id my_name display
+ target/appassembler/bin/DatastoreExample your-project-id my_name delete
+ target/appassembler/bin/DatastoreExample your-project-id my_name set myname@mydomain.com 1234
+ ```
+
+ * Here's an example run of `DnsExample`.
+
+ Note that you have to enable the Google Cloud DNS API on the [Google Developers Console][developers-console] before running the following commands.
+ You will need to replace the domain name `elaborateexample.com` with your own domain name with [verified ownership](https://www.google.com/webmasters/verification/home).
+ Also, note that the example creates and deletes record sets of type A only. Operations with other record types are not implemented in the example.
+ ```
+ target/appassembler/bin/DnsExample create some-sample-zone elaborateexample.com. description
+ target/appassembler/bin/DnsExample list
+ target/appassembler/bin/DnsExample list some-sample-zone records
+ target/appassembler/bin/DnsExample add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69
+ target/appassembler/bin/DnsExample get some-sample-zone
+ target/appassembler/bin/DnsExample delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69
+ target/appassembler/bin/DnsExample list some-sample-zone changes ascending
+ target/appassembler/bin/DnsExample delete some-sample-zone
+ ```
+
+ * Here's an example run of `LoggingExample`.
+
+ Before running the example, go to the [Google Developers Console][developers-console] to ensure
+ that Logging API is enabled.
+ ```
+ target/appassembler/bin/LoggingExample create metric test-metric severity>=ERROR
+ target/appassembler/bin/LoggingExample list metrics
+ target/appassembler/bin/LoggingExample create sink test-sink bucket test-bucket severity>=ERROR
+ target/appassembler/bin/LoggingExample list sinks
+ target/appassembler/bin/LoggingExample write test-log-name ERROR test-message test-key test-value
+ target/appassembler/bin/LoggingExample list entries
+ ```
+
+ * Here's an example run of `ParallelCountBytes`.
+
+ Before running the example, go to the [Google Developers Console][developers-console] to ensure that Google Cloud Storage API is enabled and that you have a bucket with a file in it.
+ ```
+ target/appassembler/bin/ParallelCountBytes gs://mybucket/myfile.txt
+ ```
+
+ * Here's an example run of `ResourceManagerExample`.
+
+ Be sure to change the placeholder project ID "your-project-id" with your own globally unique project ID.
+ ```
+ target/appassembler/bin/ResourceManagerExample create your-project-id
+ target/appassembler/bin/ResourceManagerExample list
+ target/appassembler/bin/ResourceManagerExample get your-project-id
+ ```
+
+ * Here's an example run of `Stat`, illustrating the use of google-cloud-nio.
+
+ Before running the example, go to the [Google Developers Console][developers-console] to ensure that Google Cloud Storage API is enabled and that you have a bucket with a file in it.
+
+ Run the sample with (from the google-cloud-examples folder):
+ ```
+ target/appassembler/bin/Stat --check
+
+ ```
+ Or, if you have a file in `gs://mybucket/myfile.txt`, you can run:
+ ```
+ target/appassembler/bin/Stat gs://mybucket/myfile.txt
+ ```
+
+ The sample doesn't have anything special about Google Cloud Storage in it, it just opens files
+ via the NIO API. It lists google-cloud-nio as a dependency, and that enables it to interpret
+ `gs://` paths.
+
+ * Here's an example run of `TranslateExample`.
+
+ Before running the example, go to the [Google Developers Console][developers-console] to ensure that "Google Translation API" is enabled.
+ ```
+ target/appassembler/bin/TranslateExample languages
+ target/appassembler/bin/TranslateExample detect Hello,\ World!
+ target/appassembler/bin/TranslateExample translate ¡Hola\ Mundo!
+ target/appassembler/bin/TranslateExample es translate Hello,\ World!
+ ```
+
+Troubleshooting
+---------------
+
+To get help, follow the instructions in the [shared Troubleshooting document](https://github.com/googleapis/google-cloud-common/blob/master/troubleshooting/readme.md#troubleshooting).
+
+Java Versions
+-------------
+
+Java 7 or above is required for using this client.
+
+Versioning
+----------
+
+This library follows [Semantic Versioning](http://semver.org/).
+
+It is currently in major version zero (``0.y.z``), which means that anything
+may change at any time and the public API should not be considered
+stable.
+
+Contributing
+------------
+
+Contributions to this library are always welcome and highly encouraged.
+
+See `google-cloud`'s [CONTRIBUTING] documentation and the [shared documentation](https://github.com/googleapis/google-cloud-common/blob/master/contributing/readme.md#how-to-contribute-to-gcloud) for more information on how to get started.
+
+Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See [Code of Conduct][code-of-conduct] for more information.
+
+License
+-------
+
+Apache 2.0 - See [LICENSE] for more information.
+
+
+[CONTRIBUTING]:https://github.com/googleapis/google-cloud-java/blob/master/CONTRIBUTING.md
+[code-of-conduct]:https://github.com/googleapis/google-cloud-java/blob/master/CODE_OF_CONDUCT.md#contributor-code-of-conduct
+[LICENSE]: https://github.com/googleapis/google-cloud-java/blob/master/LICENSE
+[cloud-platform]: https://cloud.google.com/
+[developers-console]:https://console.developers.google.com/
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/compute/README.md b/google-cloud-examples/src/main/java/com/google/cloud/examples/compute/README.md
new file mode 100644
index 000000000000..ac6555b7cd68
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/compute/README.md
@@ -0,0 +1,3 @@
+[**DEPRECATED**]
+
+The compute samples have been moved to [Java-docs-samples repository](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/main/compute/cloud-client).
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java
new file mode 100644
index 000000000000..41a79d987842
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * 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 com.google.cloud.examples.datastore;
+
+import com.google.cloud.Timestamp;
+import com.google.cloud.datastore.Datastore;
+import com.google.cloud.datastore.DatastoreOptions;
+import com.google.cloud.datastore.Entity;
+import com.google.cloud.datastore.FullEntity;
+import com.google.cloud.datastore.IncompleteKey;
+import com.google.cloud.datastore.Key;
+import com.google.cloud.datastore.KeyFactory;
+import com.google.cloud.datastore.Query;
+import com.google.cloud.datastore.QueryResults;
+import com.google.cloud.datastore.StructuredQuery;
+import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
+import com.google.cloud.datastore.Transaction;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * An example of using Google Cloud Datastore.
+ *
+ *
This example adds, displays or clears comments for a given user. This example also sets
+ * contact information for a user.
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
The first parameter is an optional {@code project_id}. The project specified in the Google
+ * Cloud SDK configuration (see {@code gcloud config list}) will be used if the project ID is not
+ * supplied. The second parameter is a DNS operation (list, delete, create, ...). The remaining
+ * arguments are specific to the operation. See each action's {@code run} method for the specific
+ * arguments.
+ */
+public class DnsExample {
+
+ private static final Map ACTIONS = new HashMap<>();
+ private static final DateTimeFormatter FORMATTER =
+ DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC);
+
+ private interface DnsAction {
+ void run(Dns dns, String... args);
+
+ String params();
+
+ boolean check(String... args);
+ }
+
+ private static class CreateZoneAction implements DnsAction {
+
+ /** Creates a zone with the provided name, DNS name and description (in this order). */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ String dnsName = args[1];
+ String description = args[2];
+ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, dnsName, description);
+ Zone zone = dns.create(zoneInfo);
+ System.out.printf(
+ "Successfully created zone with name %s which was assigned ID %s.%n",
+ zone.getName(), zone.getGeneratedId());
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 3;
+ }
+ }
+
+ private static class ListZonesAction implements DnsAction {
+
+ /** Lists all zones within the project. */
+ @Override
+ public void run(Dns dns, String... args) {
+ Iterator zoneIterator = dns.listZones().iterateAll().iterator();
+ if (zoneIterator.hasNext()) {
+ System.out.println("The project contains the following zones:");
+ while (zoneIterator.hasNext()) {
+ printZone(zoneIterator.next());
+ }
+ } else {
+ System.out.println("Project contains no zones.");
+ }
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 0;
+ }
+ }
+
+ private static class GetZoneAction implements DnsAction {
+
+ /** Gets details about a zone with the given name. */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ Zone zone = dns.getZone(zoneName);
+ if (zone == null) {
+ System.out.printf("No zone with name '%s' exists.%n", zoneName);
+ } else {
+ printZone(zone);
+ }
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 1;
+ }
+ }
+
+ private static class DeleteZoneAction implements DnsAction {
+
+ /** Deletes a zone with the given name. */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ boolean deleted = dns.delete(zoneName);
+ if (deleted) {
+ System.out.printf("Zone %s was deleted.%n", zoneName);
+ } else {
+ System.out.printf("Zone %s was NOT deleted. It does not exist.%n", zoneName);
+ }
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 1;
+ }
+ }
+
+ private static class DeleteDnsRecordAction implements DnsAction {
+
+ /**
+ * Deletes a DNS record of type A from the given zone. The last parameter is ttl and it is not
+ * required. If ttl is not provided, a default value of 0 is used. The service requires a
+ * precise match (including ttl) for deleting a record.
+ */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ String recordName = args[1];
+ String ip = args[2];
+ int ttl = 0;
+ if (args.length > 3) {
+ ttl = Integer.parseInt(args[3]);
+ }
+ RecordSet recordSet =
+ RecordSet.newBuilder(recordName, RecordSet.Type.A)
+ .setRecords(ImmutableList.of(ip))
+ .setTtl(ttl, TimeUnit.SECONDS)
+ .build();
+ ChangeRequestInfo changeRequest = ChangeRequest.newBuilder().delete(recordSet).build();
+ changeRequest = dns.applyChangeRequest(zoneName, changeRequest);
+ System.out.printf(
+ "The request for deleting A record %s for zone %s was successfully "
+ + "submitted and assigned ID %s.%n",
+ recordName, zoneName, changeRequest.getGeneratedId());
+ System.out.print("Waiting for deletion to happen...");
+ waitForChangeToFinish(dns, zoneName, changeRequest);
+ System.out.printf("%nThe deletion has been completed.%n");
+ }
+
+ @Override
+ public String params() {
+ return " []";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ if (args.length == 4) {
+ // to check that it can be parsed
+ Integer.parseInt(args[3]);
+ return true;
+ } else {
+ return args.length == 3;
+ }
+ }
+ }
+
+ private static class AddDnsRecordAction implements DnsAction {
+
+ /**
+ * Adds a record set of type A. The last parameter is ttl and is not required. If ttl is not
+ * provided, a default value of 0 will be used.
+ */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ String recordName = args[1];
+ String ip = args[2];
+ int ttl = 0;
+ if (args.length > 3) {
+ ttl = Integer.parseInt(args[3]);
+ }
+ RecordSet recordSet =
+ RecordSet.newBuilder(recordName, RecordSet.Type.A)
+ .setRecords(ImmutableList.of(ip))
+ .setTtl(ttl, TimeUnit.SECONDS)
+ .build();
+ ChangeRequestInfo changeRequest = ChangeRequest.newBuilder().add(recordSet).build();
+ changeRequest = dns.applyChangeRequest(zoneName, changeRequest);
+ System.out.printf(
+ "The request for adding A record %s for zone %s was successfully "
+ + "submitted and assigned ID %s.%n",
+ recordName, zoneName, changeRequest.getGeneratedId());
+ System.out.print("Waiting for addition to happen...");
+ waitForChangeToFinish(dns, zoneName, changeRequest);
+ System.out.printf("The addition has been completed.%n");
+ }
+
+ @Override
+ public String params() {
+ return " []";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ if (args.length == 4) {
+ // to check that it can be parsed
+ Integer.parseInt(args[3]);
+ return true;
+ } else {
+ return args.length == 3;
+ }
+ }
+ }
+
+ private static class ListDnsRecordsAction implements DnsAction {
+
+ /** Lists all the record sets in the given zone. */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ Iterator iterator = dns.listRecordSets(zoneName).iterateAll().iterator();
+ if (iterator.hasNext()) {
+ System.out.printf("Record sets for zone %s:%n", zoneName);
+ while (iterator.hasNext()) {
+ RecordSet recordSet = iterator.next();
+ System.out.printf(
+ "%nRecord name: %s%nTTL: %s%nRecords: %s%n",
+ recordSet.getName(),
+ recordSet.getTtl(),
+ Joiner.on(", ").join(recordSet.getRecords()));
+ }
+ } else {
+ System.out.printf("Zone %s has no record sets records.%n", zoneName);
+ }
+ }
+
+ @Override
+ public String params() {
+ return " records";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 2;
+ }
+ }
+
+ private static class ListChangesAction implements DnsAction {
+
+ /**
+ * Lists all the changes for a given zone. Optionally, an order ("descending" or "ascending")
+ * can be specified using the last parameter.
+ */
+ @Override
+ public void run(Dns dns, String... args) {
+ String zoneName = args[0];
+ Iterator iterator;
+ if (args.length > 2) {
+ Dns.SortingOrder sortOrder = Dns.SortingOrder.valueOf(args[2].toUpperCase());
+ iterator =
+ dns.listChangeRequests(zoneName, Dns.ChangeRequestListOption.sortOrder(sortOrder))
+ .iterateAll()
+ .iterator();
+ } else {
+ iterator = dns.listChangeRequests(zoneName).iterateAll().iterator();
+ }
+ if (iterator.hasNext()) {
+ System.out.printf("Change requests for zone %s:%n", zoneName);
+ while (iterator.hasNext()) {
+ ChangeRequest change = iterator.next();
+ System.out.printf("%nID: %s%n", change.getGeneratedId());
+ System.out.printf("Status: %s%n", change.status());
+ System.out.printf(
+ "Started: %s%n", FORMATTER.format(Instant.ofEpochMilli(change.getStartTimeMillis())));
+ System.out.printf("Deletions: %s%n", Joiner.on(", ").join(change.getDeletions()));
+ System.out.printf("Additions: %s%n", Joiner.on(", ").join(change.getAdditions()));
+ }
+ } else {
+ System.out.printf("Zone %s has no change requests.%n", zoneName);
+ }
+ }
+
+ @Override
+ public String params() {
+ return " changes [descending | ascending]";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 2
+ || (args.length == 3
+ && ImmutableList.of("descending", "ascending").contains(args[2].toLowerCase()));
+ }
+ }
+
+ private static class ListAction implements DnsAction {
+
+ /**
+ * Invokes a list action. If no parameter is provided, lists all zones. If zone name is the only
+ * parameter provided, lists both record sets and changes. Otherwise, invokes listing changes or
+ * zones based on the parameter provided.
+ */
+ @Override
+ public void run(Dns dns, String... args) {
+ if (args.length == 0) {
+ new ListZonesAction().run(dns);
+ } else {
+ if (args.length == 1 || "records".equals(args[1])) {
+ new ListDnsRecordsAction().run(dns, args);
+ }
+ if (args.length == 1 || "changes".equals(args[1])) {
+ new ListChangesAction().run(dns, args);
+ }
+ }
+ }
+
+ @Override
+ public boolean check(String... args) {
+ if (args.length == 0 || args.length == 1) {
+ return true;
+ }
+ if ("records".equals(args[1])) {
+ return new ListDnsRecordsAction().check(args);
+ }
+ if ("changes".equals(args[1])) {
+ return new ListChangesAction().check(args);
+ }
+ return false;
+ }
+
+ @Override
+ public String params() {
+ return "[ [changes [descending | ascending] | records]]";
+ }
+ }
+
+ private static class GetProjectAction implements DnsAction {
+
+ @Override
+ public void run(Dns dns, String... args) {
+ ProjectInfo project = dns.getProject();
+ ProjectInfo.Quota quota = project.getQuota();
+ System.out.printf("Project id: %s%nQuota:%n", dns.getOptions().getProjectId());
+ System.out.printf("\tZones: %d%n", quota.getZones());
+ System.out.printf("\tRecord sets per zone: %d%n", quota.getRrsetsPerZone());
+ System.out.printf("\tRecord sets per DNS record: %d%n", quota.getResourceRecordsPerRrset());
+ System.out.printf("\tAdditions per change: %d%n", quota.getRrsetAdditionsPerChange());
+ System.out.printf("\tDeletions per change: %d%n", quota.getRrsetDeletionsPerChange());
+ System.out.printf("\tTotal data size per change: %d%n", quota.getTotalRrdataSizePerChange());
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+
+ @Override
+ public boolean check(String... args) {
+ return args.length == 0;
+ }
+ }
+
+ static {
+ ACTIONS.put("create", new CreateZoneAction());
+ ACTIONS.put("delete", new DeleteZoneAction());
+ ACTIONS.put("get", new GetZoneAction());
+ ACTIONS.put("list", new ListAction());
+ ACTIONS.put("add-record", new AddDnsRecordAction());
+ ACTIONS.put("delete-record", new DeleteDnsRecordAction());
+ ACTIONS.put("quota", new GetProjectAction());
+ }
+
+ private static void printZone(Zone zone) {
+ System.out.printf("%nName: %s%n", zone.getName());
+ System.out.printf("ID: %s%n", zone.getGeneratedId());
+ System.out.printf("Description: %s%n", zone.getDescription());
+ System.out.printf(
+ "Created: %s%n", FORMATTER.format(Instant.ofEpochMilli(zone.getCreationTimeMillis())));
+ System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.getNameServers()));
+ }
+
+ private static ChangeRequestInfo waitForChangeToFinish(
+ Dns dns, String zoneName, ChangeRequestInfo request) {
+ ChangeRequestInfo current = request;
+ while (current.status().equals(ChangeRequest.Status.PENDING)) {
+ System.out.print(".");
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ System.err.println("Thread was interrupted while waiting.");
+ }
+ current = dns.getChangeRequest(zoneName, current.getGeneratedId());
+ }
+ return current;
+ }
+
+ private static void printUsage() {
+ StringBuilder actionAndParams = new StringBuilder();
+ for (Map.Entry entry : ACTIONS.entrySet()) {
+ actionAndParams.append(System.lineSeparator()).append('\t').append(entry.getKey());
+ String param = entry.getValue().params();
+ if (param != null && !param.isEmpty()) {
+ actionAndParams.append(' ').append(param);
+ }
+ }
+ System.out.printf(
+ "Usage: %s [] operation *%s%n",
+ DnsExample.class.getSimpleName(), actionAndParams);
+ }
+
+ public static void main(String... args) throws Exception {
+ if (args.length < 1) {
+ System.out.println("Missing required action");
+ printUsage();
+ return;
+ }
+ String projectId = null;
+ DnsAction action;
+ String actionName;
+ if (args.length >= 2 && !ACTIONS.containsKey(args[0])) {
+ actionName = args[1];
+ projectId = args[0];
+ args = Arrays.copyOfRange(args, 2, args.length);
+ } else {
+ actionName = args[0];
+ args = Arrays.copyOfRange(args, 1, args.length);
+ }
+ action = ACTIONS.get(actionName);
+ if (action == null) {
+ System.out.printf("Unrecognized action %s.%n", actionName);
+ printUsage();
+ return;
+ }
+ boolean valid = false;
+ try {
+ valid = action.check(args);
+ } catch (NumberFormatException ex) {
+ System.out.printf("Invalid input for action '%s'.%n", actionName);
+ System.out.println("Ttl must be an integer.");
+ System.out.printf("Expected: %s%n", action.params());
+ return;
+ } catch (Exception ex) {
+ System.out.println("Failed to parse request.");
+ System.out.printf("Expected: %s%n", action.params());
+ ex.printStackTrace();
+ return;
+ }
+ if (valid) {
+ DnsOptions.Builder optionsBuilder = DnsOptions.newBuilder();
+ if (projectId != null) {
+ optionsBuilder.setProjectId(projectId);
+ }
+ Dns dns = optionsBuilder.build().getService();
+ action.run(dns, args);
+ } else {
+ System.out.printf("Invalid input for action '%s'%n", actionName);
+ System.out.printf("Expected: %s%n", action.params());
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java
new file mode 100644
index 000000000000..10ef108491d0
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in README's and javadoc. Any change to this file should be reflected in
+ * the project's README's and package-info.java.
+ */
+
+package com.google.cloud.examples.dns.snippets;
+
+import com.google.cloud.dns.ChangeRequestInfo;
+import com.google.cloud.dns.Dns;
+import com.google.cloud.dns.DnsOptions;
+import com.google.cloud.dns.RecordSet;
+import com.google.cloud.dns.Zone;
+import java.util.concurrent.TimeUnit;
+
+/** A snippet for Google Cloud DNS showing how to create and update a resource record set. */
+public class CreateOrUpdateRecordSets {
+
+ public static void main(String... args) {
+ // Create a service object.
+ // The project ID and credentials will be inferred from the environment.
+ Dns dns = DnsOptions.getDefaultInstance().getService();
+
+ // Change this to a zone name that exists within your project
+ String zoneName = "my-unique-zone";
+
+ // Get zone from the service
+ Zone zone = dns.getZone(zoneName);
+
+ // Prepare a www.. type A record set with ttl of 24 hours
+ String ip = "12.13.14.15";
+ RecordSet toCreate =
+ RecordSet.newBuilder("www." + zone.getDnsName(), RecordSet.Type.A)
+ .setTtl(24, TimeUnit.HOURS)
+ .addRecord(ip)
+ .build();
+
+ // Make a change
+ ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.newBuilder().add(toCreate);
+
+ // Verify a www.. type A record does not exist yet.
+ // If it does exist, we will overwrite it with our prepared record.
+ for (RecordSet current : zone.listRecordSets().iterateAll()) {
+ if (toCreate.getName().equals(current.getName())
+ && toCreate.getType().equals(current.getType())) {
+ changeBuilder.delete(current);
+ }
+ }
+
+ // Build and apply the change request to our zone
+ ChangeRequestInfo changeRequest = changeBuilder.build();
+ zone.applyChangeRequest(changeRequest);
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java
new file mode 100644
index 000000000000..a3347ef9b599
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in README's and javadoc. Any change to this file should be reflected in
+ * the project's README's and package-info.java.
+ */
+
+package com.google.cloud.examples.dns.snippets;
+
+import com.google.cloud.dns.Dns;
+import com.google.cloud.dns.DnsOptions;
+import com.google.cloud.dns.Zone;
+import com.google.cloud.dns.ZoneInfo;
+
+/**
+ * A snippet for Google Cloud DNS showing how to create a zone. You will need to change the {@code
+ * domainName} to a domain name, the ownership of which you should verify with Google.
+ */
+public class CreateZone {
+
+ public static void main(String... args) {
+ // Create a service object
+ // The project ID and credentials will be inferred from the environment.
+ Dns dns = DnsOptions.getDefaultInstance().getService();
+
+ // Create a zone metadata object
+ String zoneName = "my-unique-zone"; // Change this zone name which is unique within your project
+ String domainName = "someexampledomain.com."; // Change this to a domain which you own
+ String description = "This is a google-cloud-dns sample zone.";
+ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description);
+
+ // Create zone in Google Cloud DNS
+ Zone zone = dns.create(zoneInfo);
+ System.out.printf("Zone was created and assigned ID %s.%n", zone.getGeneratedId());
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java
new file mode 100644
index 000000000000..38473cb03a27
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in README's and javadoc. Any change to this file should be reflected in
+ * the project's README's and package-info.java.
+ */
+
+package com.google.cloud.examples.dns.snippets;
+
+import com.google.cloud.dns.ChangeRequest;
+import com.google.cloud.dns.ChangeRequestInfo;
+import com.google.cloud.dns.Dns;
+import com.google.cloud.dns.DnsOptions;
+import com.google.cloud.dns.RecordSet;
+
+/**
+ * A snippet for Google Cloud DNS showing how to delete a zone. It also shows how to list and delete
+ * DNS records.
+ */
+public class DeleteZone {
+
+ public static void main(String... args) {
+ // Create a service object.
+ // The project ID and credentials will be inferred from the environment.
+ Dns dns = DnsOptions.getDefaultInstance().getService();
+
+ // Change this to a zone name that exists within your project and that you want to delete.
+ String zoneName = "my-unique-zone";
+
+ // Get iterable for the existing record sets which have to be deleted before deleting the zone
+ Iterable recordIterable = dns.listRecordSets(zoneName).iterateAll();
+
+ // Make a change for deleting the records
+ ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.newBuilder();
+ for (RecordSet current : recordIterable) {
+ // SOA and NS records cannot be deleted
+ if (!RecordSet.Type.SOA.equals(current.getType())
+ && !RecordSet.Type.NS.equals(current.getType())) {
+ changeBuilder.delete(current);
+ }
+ }
+
+ // Build and apply the change request to our zone if it contains records to delete
+ ChangeRequestInfo changeRequest = changeBuilder.build();
+ if (!changeRequest.getDeletions().isEmpty()) {
+ ChangeRequest pendingRequest = dns.applyChangeRequest(zoneName, changeRequest);
+
+ // Wait for the change request to complete
+ while (!pendingRequest.isDone()) {
+ System.out.println("Waiting for change to complete. Going to sleep for 500ms...");
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ System.err.println(
+ "The thread was interrupted while waiting for change request to be " + "processed.");
+ }
+ }
+ }
+
+ // Delete the zone
+ boolean result = dns.delete(zoneName);
+ if (result) {
+ System.out.println("Zone was deleted.");
+ } else {
+ System.out.println("Zone was not deleted because it does not exist.");
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java
new file mode 100644
index 000000000000..68d690e60e5b
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in README's and javadoc. Any change to this file should be reflected in
+ * the project's README's and package-info.java.
+ */
+
+package com.google.cloud.examples.dns.snippets;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.dns.ChangeRequest;
+import com.google.cloud.dns.ChangeRequestInfo;
+import com.google.cloud.dns.Dns;
+import com.google.cloud.dns.DnsOptions;
+import com.google.cloud.dns.RecordSet;
+import com.google.cloud.dns.Zone;
+import com.google.cloud.dns.ZoneInfo;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A complete snippet for Google Cloud DNS showing how to create and delete a zone. It also shows
+ * how to create, list and delete record sets, and how to list changes.
+ */
+public class ManipulateZonesAndRecordSets {
+
+ public static void main(String... args) {
+ Dns dns = DnsOptions.getDefaultInstance().getService();
+
+ // Create a zone metadata object
+ String zoneName = "my-unique-zone"; // Change this zone name which is unique within your project
+ String domainName = "someexampledomain.com."; // Change this to a domain which you own
+ String description = "This is a google-cloud-dns sample zone.";
+ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description);
+
+ // Create zone in Google Cloud DNS
+ Zone zone = dns.create(zoneInfo);
+ System.out.printf("Zone was created and assigned ID %s.%n", zone.getGeneratedId());
+
+ // Print assigned name servers
+ List nameServers = zone.getNameServers();
+ for (String nameServer : nameServers) {
+ System.out.println(nameServer);
+ }
+
+ // Prepare a www.someexampledomain.com. type A record with ttl of 24 hours
+ String ip = "12.13.14.15";
+ RecordSet toCreate =
+ RecordSet.newBuilder("www.someexampledomain.com.", RecordSet.Type.A)
+ .setTtl(24, TimeUnit.HOURS)
+ .addRecord(ip)
+ .build();
+
+ // Make a change
+ ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.newBuilder().add(toCreate);
+
+ // Verify the type A record does not exist yet.
+ // If it does exist, we will overwrite it with our prepared record.
+ Page recordSetPage = zone.listRecordSets();
+ for (RecordSet current : recordSetPage.iterateAll()) {
+ if (toCreate.getName().equals(current.getName())
+ && toCreate.getType().equals(current.getType())) {
+ changeBuilder.delete(current);
+ }
+ }
+
+ // Build and apply the change request to our zone
+ ChangeRequestInfo changeRequest = changeBuilder.build();
+ zone.applyChangeRequest(changeRequest);
+
+ while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) {
+ try {
+ Thread.sleep(500L);
+ } catch (InterruptedException e) {
+ System.err.println("The thread was interrupted while waiting...");
+ }
+ changeRequest = dns.getChangeRequest(zone.getName(), changeRequest.getGeneratedId());
+ }
+ System.out.println("The change request has been applied.");
+
+ // List all your zones
+ int counter = 1;
+ for (Zone currentZone : dns.listZones().iterateAll()) {
+ System.out.printf("#%d.: %s%n%n", counter, currentZone);
+ counter++;
+ }
+
+ // List the record sets in a particular zone
+ System.out.println(String.format("Record sets inside %s:", zone.getName()));
+ for (RecordSet recordSet : recordSetPage.iterateAll()) {
+ System.out.println(recordSet);
+ }
+
+ // List the change requests applied to a particular zone
+ System.out.println(String.format("The history of changes in %s:", zone.getName()));
+ for (ChangeRequest currentChangeRequest : zone.listChangeRequests().iterateAll()) {
+ System.out.println(currentChangeRequest);
+ }
+
+ // Make a change for deleting the record sets
+ changeBuilder = ChangeRequestInfo.newBuilder();
+ for (RecordSet current : recordSetPage.iterateAll()) {
+ // SOA and NS records cannot be deleted
+ if (!RecordSet.Type.SOA.equals(current.getType())
+ && !RecordSet.Type.NS.equals(current.getType())) {
+ changeBuilder.delete(current);
+ }
+ }
+
+ // Build and apply the change request to our zone if it contains records to delete
+ changeRequest = changeBuilder.build();
+ if (!changeRequest.getDeletions().isEmpty()) {
+ ChangeRequest pendingRequest = dns.applyChangeRequest(zoneName, changeRequest);
+
+ // Wait for the change request to complete
+ while (!pendingRequest.isDone()) {
+ System.out.println("Waiting for change to complete. Going to sleep for 500ms...");
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ System.err.println(
+ "The thread was interrupted while waiting for change request to be " + "processed.");
+ }
+ }
+ }
+
+ // Delete the zone
+ boolean result = dns.delete(zoneName);
+ if (result) {
+ System.out.println("Zone was deleted.");
+ } else {
+ System.out.println("Zone was not deleted because it does not exist.");
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/language/snippets/AnalyzeSentiment.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/language/snippets/AnalyzeSentiment.java
new file mode 100644
index 000000000000..26c8334e039a
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/language/snippets/AnalyzeSentiment.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in READMEs. Any change to this file should be reflected in
+ * the project's READMEs.
+ */
+
+package com.google.cloud.examples.language.snippets;
+
+import com.google.cloud.language.v1.Document;
+import com.google.cloud.language.v1.Document.Type;
+import com.google.cloud.language.v1.LanguageServiceClient;
+import com.google.cloud.language.v1.Sentiment;
+
+/** A snippet for Google Cloud Speech API showing how to analyze text message sentiment. */
+public class AnalyzeSentiment {
+
+ public static void main(String... args) throws Exception {
+ // Instantiates a client
+ LanguageServiceClient language = LanguageServiceClient.create();
+
+ // The text to analyze
+ String[] texts = {"I love this!", "I hate this!"};
+ for (String text : texts) {
+ Document doc = Document.newBuilder().setContent(text).setType(Type.PLAIN_TEXT).build();
+ // Detects the sentiment of the text
+ Sentiment sentiment = language.analyzeSentiment(doc).getDocumentSentiment();
+
+ System.out.printf("Text: \"%s\"%n", text);
+ System.out.printf(
+ "Sentiment: score = %s, magnitude = %s%n",
+ sentiment.getScore(), sentiment.getMagnitude());
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/LoggingExample.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/LoggingExample.java
new file mode 100644
index 000000000000..ba305e30f607
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/LoggingExample.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.logging;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.MonitoredResource;
+import com.google.cloud.MonitoredResourceDescriptor;
+import com.google.cloud.Tuple;
+import com.google.cloud.logging.LogEntry;
+import com.google.cloud.logging.Logging;
+import com.google.cloud.logging.Logging.EntryListOption;
+import com.google.cloud.logging.LoggingOptions;
+import com.google.cloud.logging.Metric;
+import com.google.cloud.logging.MetricInfo;
+import com.google.cloud.logging.Payload.StringPayload;
+import com.google.cloud.logging.Severity;
+import com.google.cloud.logging.Sink;
+import com.google.cloud.logging.SinkInfo;
+import com.google.cloud.logging.SinkInfo.Destination;
+import com.google.cloud.logging.SinkInfo.Destination.BucketDestination;
+import com.google.cloud.logging.SinkInfo.Destination.DatasetDestination;
+import com.google.cloud.logging.SinkInfo.Destination.TopicDestination;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An example of using Stackdriver Logging.
+ *
+ *
This example demonstrates a simple/typical Logging usage.
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
{@code target/appassembler/bin/LoggingExample
+ * -Dexec.args="[]
+ * create metric
+ * create sink bucket|dataset|topic ?
+ * list metrics
+ * list sinks
+ * list resource-descriptors
+ * list entries ?
+ * delete metric
+ * delete sink
+ * delete log
+ * into metric
+ * info sink
+ * write ()*"}
+ *
+ *
The first parameter is an optional {@code project_id} (logged-in project will be used if not
+ * supplied). Second parameter is a Logging operation and can be used to demonstrate its usage. For
+ * operations that apply to more than one entity (`list`, `create`, `info` and `delete`) the third
+ * parameter specifies the entity.
+ */
+public class LoggingExample {
+
+ private static final Map CREATE_ACTIONS = new HashMap<>();
+ private static final Map INFO_ACTIONS = new HashMap<>();
+ private static final Map LIST_ACTIONS = new HashMap<>();
+ private static final Map DELETE_ACTIONS = new HashMap<>();
+ private static final Map ACTIONS = new HashMap<>();
+
+ private abstract static class LoggingAction {
+
+ abstract void run(Logging logging, T arg) throws Exception;
+
+ abstract T parse(String... args) throws Exception;
+
+ protected String params() {
+ return "";
+ }
+ }
+
+ private static class ParentAction extends LoggingAction> {
+
+ private final Map subActions;
+
+ ParentAction(Map subActions) {
+ this.subActions = ImmutableMap.copyOf(subActions);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ void run(Logging logging, Tuple subaction) throws Exception {
+ subaction.x().run(logging, subaction.y());
+ }
+
+ @Override
+ Tuple parse(String... args) throws Exception {
+ if (args.length >= 1) {
+ LoggingAction action = subActions.get(args[0]);
+ if (action != null) {
+ Object actionArguments = action.parse(Arrays.copyOfRange(args, 1, args.length));
+ return Tuple.of(action, actionArguments);
+ } else {
+ throw new IllegalArgumentException("Unrecognized entity '" + args[0] + "'.");
+ }
+ }
+ throw new IllegalArgumentException("Missing required entity.");
+ }
+
+ @Override
+ public String params() {
+ StringBuilder builder = new StringBuilder();
+ for (Map.Entry entry : subActions.entrySet()) {
+ builder.append('\n').append(entry.getKey());
+ String param = entry.getValue().params();
+ if (param != null && !param.isEmpty()) {
+ builder.append(' ').append(param);
+ }
+ }
+ return builder.toString();
+ }
+ }
+
+ private abstract static class NoArgsAction extends LoggingAction {
+ @Override
+ Void parse(String... args) throws Exception {
+ if (args.length == 0) {
+ return null;
+ }
+ throw new IllegalArgumentException("This action takes no arguments.");
+ }
+ }
+
+ /**
+ * This class demonstrates how to list Logging metrics.
+ *
+ * @see
+ * List metrics
+ */
+ private static class ListMetricsAction extends NoArgsAction {
+ @Override
+ public void run(Logging logging, Void arg) {
+ for (Metric metric : logging.listMetrics().iterateAll()) {
+ System.out.println(metric);
+ }
+ }
+ }
+
+ private abstract static class MetricAction extends LoggingAction {
+ @Override
+ String parse(String... args) throws Exception {
+ String message;
+ if (args.length == 1) {
+ return args[0];
+ } else if (args.length > 1) {
+ message = "Too many arguments.";
+ } else {
+ message = "Missing required metric name.";
+ }
+ throw new IllegalArgumentException(message);
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+ }
+
+ /**
+ * This class demonstrates how to retrieve information on a Logging metric.
+ *
+ * @see
+ * Get metric
+ */
+ private static class MetricInfoAction extends MetricAction {
+ @Override
+ public void run(Logging logging, String metric) {
+ System.out.printf("Metric info: %s%n", logging.getMetric(metric));
+ }
+ }
+
+ /**
+ * This class demonstrates how to delete a Logging metric.
+ *
+ * @see
+ * Delete a metric
+ */
+ private static class DeleteMetricAction extends MetricAction {
+ @Override
+ public void run(Logging logging, String metric) {
+ logging.deleteMetric(metric);
+ System.out.printf("Deleted metric %s%n", metric);
+ }
+ }
+
+ /**
+ * This class demonstrates how to create a Logging metric.
+ *
+ * @see
+ * Create a metric
+ */
+ private static class CreateMetricAction extends LoggingAction {
+ @Override
+ public void run(Logging logging, MetricInfo metric) {
+ System.out.printf("Created metric %s%n", logging.create(metric));
+ }
+
+ @Override
+ MetricInfo parse(String... args) throws Exception {
+ String message;
+ if (args.length == 2) {
+ return MetricInfo.of(args[0], args[1]);
+ } else if (args.length > 2) {
+ message = "Too many arguments.";
+ } else {
+ message = "Missing required metric name or filter.";
+ }
+ throw new IllegalArgumentException(message);
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+ }
+
+ /**
+ * This class demonstrates how to list Logging sinks.
+ *
+ * @see
+ * List sinks
+ */
+ private static class ListSinksAction extends NoArgsAction {
+ @Override
+ public void run(Logging logging, Void arg) {
+ for (Sink sink : logging.listSinks().iterateAll()) {
+ System.out.println(sink);
+ }
+ }
+ }
+
+ private abstract static class SinkAction extends LoggingAction {
+ @Override
+ String parse(String... args) throws Exception {
+ String message;
+ if (args.length == 1) {
+ return args[0];
+ } else if (args.length > 1) {
+ message = "Too many arguments.";
+ } else {
+ message = "Missing required sink name.";
+ }
+ throw new IllegalArgumentException(message);
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+ }
+
+ /**
+ * This class demonstrates how to retrieve information on a Logging sink.
+ *
+ * @see
+ * Get sink
+ */
+ private static class SinkInfoAction extends SinkAction {
+ @Override
+ public void run(Logging logging, String sink) {
+ System.out.printf("Sink info: %s%n", logging.getSink(sink));
+ }
+ }
+
+ /**
+ * This class demonstrates how to delete a Logging sink.
+ *
+ * @see
+ * Delete a sink
+ */
+ private static class DeleteSinkAction extends SinkAction {
+ @Override
+ public void run(Logging logging, String sink) {
+ logging.deleteSink(sink);
+ System.out.printf("Deleted sink %s%n", sink);
+ }
+ }
+
+ /**
+ * This class demonstrates how to create a Logging sink.
+ *
+ * @see
+ * Create a sink
+ */
+ private static class CreateSinkAction extends LoggingAction {
+ @Override
+ public void run(Logging logging, SinkInfo sink) {
+ System.out.printf("Created sink %s%n", logging.create(sink));
+ }
+
+ @Override
+ SinkInfo parse(String... args) throws Exception {
+ if (args.length >= 3) {
+ if (args.length > 4) {
+ throw new IllegalArgumentException("Too many arguments.");
+ }
+ String name = args[0];
+ Destination destination;
+ switch (args[1]) {
+ case "bucket":
+ destination = BucketDestination.of(args[2]);
+ break;
+ case "dataset":
+ destination = DatasetDestination.of(args[2]);
+ break;
+ case "topic":
+ destination = TopicDestination.of(args[2]);
+ break;
+ default:
+ throw new IllegalArgumentException("Second argument must be bucket|dataset|topic.");
+ }
+ SinkInfo.Builder builder = SinkInfo.newBuilder(name, destination);
+ if (args.length == 4) {
+ builder.setFilter(args[3]);
+ }
+ return builder.build();
+ }
+ throw new IllegalArgumentException("Missing required sink name, destination or filter.");
+ }
+
+ @Override
+ public String params() {
+ return " bucket|dataset|topic ?";
+ }
+ }
+
+ /**
+ * This class demonstrates how to list Logging monitored resource descriptors.
+ *
+ * @see
+ * List monitored resource descriptor
+ */
+ private static class ListResourceDescriptorsAction extends NoArgsAction {
+ @Override
+ public void run(Logging logging, Void arg) {
+ for (MonitoredResourceDescriptor descriptor :
+ logging.listMonitoredResourceDescriptors().iterateAll()) {
+ System.out.println(descriptor);
+ }
+ }
+ }
+
+ /**
+ * This class demonstrates how to write Logging entries.
+ *
+ * @see
+ * Write log entries
+ */
+ private static class WriteEntryAction extends LoggingAction {
+
+ @Override
+ public void run(Logging logging, LogEntry entry) {
+ MonitoredResource resource =
+ MonitoredResource.newBuilder("global")
+ .addLabel("project_id", logging.getOptions().getProjectId())
+ .build();
+ LogEntry entryWithResource = entry.toBuilder().setResource(resource).build();
+ logging.write(Collections.singleton(entryWithResource));
+ System.out.printf("Written entry %s%n", entryWithResource);
+ }
+
+ @Override
+ LogEntry parse(String... args) throws Exception {
+ if (args.length >= 3) {
+ if ((args.length & 0x1) != 0x1) {
+ throw new IllegalArgumentException("Labels must be a list of key-value pairs.");
+ }
+ String logName = args[0];
+ Severity severity = Severity.valueOf(args[1].toUpperCase());
+ String message = args[2];
+ Map labels = Maps.newHashMapWithExpectedSize((args.length - 3) / 2);
+ for (int i = 3; i < args.length; i += 2) {
+ labels.put(args[i], args[i + 1]);
+ }
+ return LogEntry.newBuilder(StringPayload.of(message))
+ .setLogName(logName)
+ .setSeverity(severity)
+ .setLabels(labels)
+ .build();
+ } else {
+ throw new IllegalArgumentException("Missing required arguments.");
+ }
+ }
+
+ @Override
+ public String params() {
+ return " ()*";
+ }
+ }
+
+ /**
+ * This class demonstrates how to list Logging entries.
+ *
+ * @see
+ * List log entries
+ */
+ private static class ListEntriesAction extends LoggingAction {
+ @Override
+ public void run(Logging logging, String filter) {
+ Page entryPage;
+ if (filter == null) {
+ entryPage = logging.listLogEntries();
+ } else {
+ entryPage = logging.listLogEntries(EntryListOption.filter(filter));
+ }
+ for (LogEntry entry : entryPage.iterateAll()) {
+ System.out.println(entry);
+ }
+ }
+
+ @Override
+ String parse(String... args) throws Exception {
+ if (args.length == 0) {
+ return null;
+ } else if (args.length == 1) {
+ return args[0];
+ }
+ throw new IllegalArgumentException("Too many arguments.");
+ }
+
+ @Override
+ public String params() {
+ return "?";
+ }
+ }
+
+ /**
+ * This class demonstrates how to delete a Logging log.
+ *
+ * @see
+ * Delete a log
+ */
+ private static class DeleteLogAction extends LoggingAction {
+ @Override
+ public void run(Logging logging, String logName) {
+ logging.deleteLog(logName);
+ System.out.printf("Deleted log %s%n", logName);
+ }
+
+ @Override
+ String parse(String... args) throws Exception {
+ String message;
+ if (args.length == 1) {
+ return args[0];
+ } else if (args.length > 1) {
+ message = "Too many arguments.";
+ } else {
+ message = "Missing required log name.";
+ }
+ throw new IllegalArgumentException(message);
+ }
+
+ @Override
+ public String params() {
+ return "";
+ }
+ }
+
+ static {
+ CREATE_ACTIONS.put("metric", new CreateMetricAction());
+ CREATE_ACTIONS.put("sink", new CreateSinkAction());
+ INFO_ACTIONS.put("metric", new MetricInfoAction());
+ INFO_ACTIONS.put("sink", new SinkInfoAction());
+ LIST_ACTIONS.put("metrics", new ListMetricsAction());
+ LIST_ACTIONS.put("sinks", new ListSinksAction());
+ LIST_ACTIONS.put("entries", new ListEntriesAction());
+ LIST_ACTIONS.put("resource-descriptors", new ListResourceDescriptorsAction());
+ DELETE_ACTIONS.put("metric", new DeleteMetricAction());
+ DELETE_ACTIONS.put("sink", new DeleteSinkAction());
+ DELETE_ACTIONS.put("log", new DeleteLogAction());
+ ACTIONS.put("create", new ParentAction(CREATE_ACTIONS));
+ ACTIONS.put("info", new ParentAction(INFO_ACTIONS));
+ ACTIONS.put("list", new ParentAction(LIST_ACTIONS));
+ ACTIONS.put("delete", new ParentAction(DELETE_ACTIONS));
+ ACTIONS.put("write", new WriteEntryAction());
+ }
+
+ private static void printUsage() {
+ StringBuilder actionAndParams = new StringBuilder();
+ for (Map.Entry entry : ACTIONS.entrySet()) {
+ actionAndParams.append("\n\t").append(entry.getKey());
+
+ String param = entry.getValue().params();
+ if (param != null && !param.isEmpty()) {
+ actionAndParams.append(' ').append(param.replace("\n", "\n\t\t"));
+ }
+ }
+ System.out.printf(
+ "Usage: %s [] operation [entity] *%s%n",
+ LoggingExample.class.getSimpleName(), actionAndParams);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void main(String... args) throws Exception {
+ if (args.length < 1) {
+ System.out.println("Missing required project id and action");
+ printUsage();
+ return;
+ }
+ LoggingOptions.Builder optionsBuilder = LoggingOptions.newBuilder();
+ LoggingAction action;
+ String actionName;
+ if (args.length >= 2 && !ACTIONS.containsKey(args[0])) {
+ actionName = args[1];
+ optionsBuilder.setProjectId(args[0]);
+ action = ACTIONS.get(args[1]);
+ args = Arrays.copyOfRange(args, 2, args.length);
+ } else {
+ actionName = args[0];
+ action = ACTIONS.get(args[0]);
+ args = Arrays.copyOfRange(args, 1, args.length);
+ }
+ if (action == null) {
+ System.out.println("Unrecognized action.");
+ printUsage();
+ return;
+ }
+ try (Logging logging = optionsBuilder.build().getService()) {
+ Object arg;
+ try {
+ arg = action.parse(args);
+ } catch (IllegalArgumentException ex) {
+ System.out.printf("Invalid input for action '%s'. %s%n", actionName, ex.getMessage());
+ System.out.printf("Expected: %s%n", action.params());
+ return;
+ } catch (Exception ex) {
+ System.out.println("Failed to parse arguments.");
+ ex.printStackTrace();
+ return;
+ }
+ action.run(logging, arg);
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/AddLoggingHandler.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/AddLoggingHandler.java
new file mode 100644
index 000000000000..fce5536696f5
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/AddLoggingHandler.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.logging.snippets;
+
+import com.google.cloud.logging.LoggingHandler;
+import java.util.logging.Logger;
+
+/**
+ * A snippet showing how to use {@link java.util.logging.Logger} to log entries to Stackdriver
+ * Logging. The snippet shows how to install a Stackdriver Logging handler using {@link
+ * com.google.cloud.logging.LoggingHandler#addHandler(Logger, LoggingHandler)}. Notice that this
+ * could also be done through the {@code logging.properties} file, adding the following line:
+ *
+ *
+ */
+public class AddLoggingHandler {
+
+ private static final Logger LOGGER = Logger.getLogger(AddLoggingHandler.class.getName());
+
+ public static void main(String... args) {
+ // Add the Stackdriver Logging handler
+ LoggingHandler.addHandler(LOGGER, new LoggingHandler());
+
+ // log using the logger
+ LOGGER.warning("test warning");
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListMetrics.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListMetrics.java
new file mode 100644
index 000000000000..0fed2e679be9
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListMetrics.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.logging.snippets;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.logging.Logging;
+import com.google.cloud.logging.LoggingOptions;
+import com.google.cloud.logging.Metric;
+import com.google.cloud.logging.MetricInfo;
+
+/**
+ * A snippet for Stackdriver Logging showing how to create a metric. The snippet also shows how to
+ * list all metrics.
+ *
+ * @see Log-based metrics
+ *
+ */
+public class CreateAndListMetrics {
+
+ public static void main(String... args) throws Exception {
+ // Create a service object
+ // Credentials are inferred from the environment
+ try (Logging logging = LoggingOptions.getDefaultInstance().getService()) {
+
+ // Create a metric
+ MetricInfo metricInfo =
+ MetricInfo.newBuilder("test-metric", "severity >= ERROR")
+ .setDescription("Log entries with severity higher or equal to ERROR")
+ .build();
+ logging.create(metricInfo);
+
+ // List metrics
+ Page metrics = logging.listMetrics();
+ for (Metric metric : metrics.iterateAll()) {
+ System.out.println(metric);
+ }
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListSinks.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListSinks.java
new file mode 100644
index 000000000000..205092b2436e
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/CreateAndListSinks.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.logging.snippets;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.logging.Logging;
+import com.google.cloud.logging.LoggingOptions;
+import com.google.cloud.logging.Sink;
+import com.google.cloud.logging.SinkInfo;
+import com.google.cloud.logging.SinkInfo.Destination.DatasetDestination;
+
+/**
+ * A snippet for Stackdriver Logging showing how to create a sink to backs log entries to BigQuery.
+ * The snippet also shows how to list all sinks.
+ *
+ * @see Sinks
+ */
+public class CreateAndListSinks {
+
+ public static void main(String... args) throws Exception {
+ // Create a service object
+ // Credentials are inferred from the environment
+ try (Logging logging = LoggingOptions.getDefaultInstance().getService()) {
+
+ // Create a sink to back log entries to a BigQuery dataset
+ SinkInfo sinkInfo =
+ SinkInfo.newBuilder("test-sink", DatasetDestination.of("test-dataset"))
+ .setFilter("severity >= ERROR")
+ .build();
+ logging.create(sinkInfo);
+
+ // List sinks
+ Page sinks = logging.listSinks();
+ for (Sink sink : sinks.iterateAll()) {
+ System.out.println(sink);
+ }
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java
new file mode 100644
index 000000000000..4810dacb3e98
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in Logging's javadoc. Any change to this file should be reflected in
+ * Logging's javadoc.
+ */
+
+package com.google.cloud.examples.logging.snippets;
+
+import com.google.api.gax.paging.AsyncPage;
+import com.google.api.gax.paging.Page;
+import com.google.cloud.MonitoredResource;
+import com.google.cloud.MonitoredResourceDescriptor;
+import com.google.cloud.logging.LogEntry;
+import com.google.cloud.logging.Logging;
+import com.google.cloud.logging.Logging.EntryListOption;
+import com.google.cloud.logging.Logging.ListOption;
+import com.google.cloud.logging.Logging.WriteOption;
+import com.google.cloud.logging.LoggingOptions;
+import com.google.cloud.logging.Metric;
+import com.google.cloud.logging.MetricInfo;
+import com.google.cloud.logging.Payload.JsonPayload;
+import com.google.cloud.logging.Payload.StringPayload;
+import com.google.cloud.logging.Sink;
+import com.google.cloud.logging.SinkInfo;
+import com.google.cloud.logging.SinkInfo.Destination.DatasetDestination;
+import com.google.cloud.logging.Synchronicity;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class LoggingSnippets {
+
+ private final Logging logging;
+
+ public LoggingSnippets(Logging logging) {
+ this.logging = logging;
+ }
+
+ /**
+ * Example of creating a sink to export logs to a BigQuery dataset (in the {@link
+ * LoggingOptions#getProjectId()} project).
+ */
+ // [TARGET create(SinkInfo)]
+ // [VARIABLE "my_sink_name"]
+ // [VARIABLE "my_dataset"]
+ public Sink createSink(String sinkName, String datasetName) {
+ // [START logging_create_sink]
+ SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName));
+ Sink sink = logging.create(sinkInfo);
+ // [END logging_create_sink]
+ return sink;
+ }
+
+ /**
+ * Example of asynchronously creating a sink to export logs to a BigQuery dataset (in the {@link
+ * LoggingOptions#getProjectId()} project).
+ */
+ // [TARGET createAsync(SinkInfo)]
+ // [VARIABLE "my_sink_name"]
+ // [VARIABLE "my_dataset"]
+ public Sink createSinkAsync(String sinkName, String datasetName)
+ throws ExecutionException, InterruptedException {
+ // [START createSinkAsync]
+ SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName));
+ Future future = logging.createAsync(sinkInfo);
+ // ...
+ Sink sink = future.get();
+ // [END createSinkAsync]
+ return sink;
+ }
+
+ /** Example of updating a sink. */
+ // [TARGET update(SinkInfo)]
+ // [VARIABLE "my_sink_name"]
+ // [VARIABLE "my_dataset"]
+ public Sink updateSink(String sinkName, String datasetName) {
+ // [START logging_update_sink]
+ SinkInfo sinkInfo =
+ SinkInfo.newBuilder(sinkName, DatasetDestination.of(datasetName))
+ .setVersionFormat(SinkInfo.VersionFormat.V2)
+ .setFilter("severity>=ERROR")
+ .build();
+ Sink sink = logging.update(sinkInfo);
+ // [END logging_update_sink]
+ return sink;
+ }
+
+ /** Example of asynchronously updating a sink. */
+ // [TARGET updateAsync(SinkInfo)]
+ // [VARIABLE "my_sink_name"]
+ // [VARIABLE "my_dataset"]
+ public Sink updateSinkAsync(String sinkName, String datasetName)
+ throws ExecutionException, InterruptedException {
+ // [START updateSinkAsync]
+ SinkInfo sinkInfo =
+ SinkInfo.newBuilder(sinkName, DatasetDestination.of(datasetName))
+ .setVersionFormat(SinkInfo.VersionFormat.V2)
+ .setFilter("severity>=ERROR")
+ .build();
+ Future future = logging.updateAsync(sinkInfo);
+ // ...
+ Sink sink = future.get();
+ // [END updateSinkAsync]
+ return sink;
+ }
+
+ /** Example of getting a sink. */
+ // [TARGET getSink(String)]
+ // [VARIABLE "my_sink_name"]
+ public Sink getSink(String sinkName) {
+ // [START getSink]
+ Sink sink = logging.getSink(sinkName);
+ if (sink == null) {
+ // sink was not found
+ }
+ // [END getSink]
+ return sink;
+ }
+
+ /** Example of asynchronously getting a sink. */
+ // [TARGET getSinkAsync(String)]
+ // [VARIABLE "my_sink_name"]
+ public Sink getSinkAsync(String sinkName) throws ExecutionException, InterruptedException {
+ // [START getSinkAsync]
+ Future future = logging.getSinkAsync(sinkName);
+ // ...
+ Sink sink = future.get();
+ if (sink == null) {
+ // sink was not found
+ }
+ // [END getSinkAsync]
+ return sink;
+ }
+
+ /** Example of listing sinks, specifying the page size. */
+ // [TARGET listSinks(ListOption...)]
+ public Page listSinks() {
+ // [START logging_list_sinks]
+ Page sinks = logging.listSinks(ListOption.pageSize(100));
+ for (Sink sink : sinks.iterateAll()) {
+ // do something with the sink
+ }
+ // [END logging_list_sinks]
+ return sinks;
+ }
+
+ /** Example of asynchronously listing sinks, specifying the page size. */
+ // [TARGET listSinksAsync(ListOption...)]
+ public Page listSinksAsync() throws ExecutionException, InterruptedException {
+ // [START listSinksAsync]
+ Future> future = logging.listSinksAsync(ListOption.pageSize(100));
+ // ...
+ AsyncPage sinks = future.get();
+ for (Sink sink : sinks.iterateAll()) {
+ // do something with the sink
+ }
+ // [END listSinksAsync]
+ return sinks;
+ }
+
+ /** Example of deleting a sink. */
+ // [TARGET deleteSink(String)]
+ // [VARIABLE "my_sink_name"]
+ public boolean deleteSink(String sinkName) {
+ // [START logging_delete_sink]
+ boolean deleted = logging.deleteSink(sinkName);
+ if (deleted) {
+ // the sink was deleted
+ } else {
+ // the sink was not found
+ }
+ // [END logging_delete_sink]
+ return deleted;
+ }
+
+ /** Example of asynchronously deleting a sink. */
+ // [TARGET deleteSinkAsync(String)]
+ // [VARIABLE "my_sink_name"]
+ public boolean deleteSinkAsync(String sinkName) throws ExecutionException, InterruptedException {
+ // [START deleteSinkAsync]
+ Future future = logging.deleteSinkAsync(sinkName);
+ // ...
+ boolean deleted = future.get();
+ if (deleted) {
+ // the sink was deleted
+ } else {
+ // the sink was not found
+ }
+ // [END deleteSinkAsync]
+ return deleted;
+ }
+
+ /** Example of deleting a log. */
+ // [TARGET deleteLog(String)]
+ // [VARIABLE "my_log_name"]
+ public boolean deleteLog(String logName) {
+ // [START logging_delete_log]
+ boolean deleted = logging.deleteLog(logName);
+ if (deleted) {
+ // the log was deleted
+ } else {
+ // the log was not found
+ }
+ // [END logging_delete_log]
+ return deleted;
+ }
+
+ /** Example of asynchronously deleting a log. */
+ // [TARGET deleteLogAsync(String)]
+ // [VARIABLE "my_log_name"]
+ public boolean deleteLogAsync(String logName) throws ExecutionException, InterruptedException {
+ // [START deleteLogAsync]
+ Future future = logging.deleteLogAsync(logName);
+ // ...
+ boolean deleted = future.get();
+ if (deleted) {
+ // the log was deleted
+ } else {
+ // the log was not found
+ }
+ // [END deleteLogAsync]
+ return deleted;
+ }
+
+ /** Example of listing monitored resource descriptors, specifying the page size. */
+ // [TARGET listMonitoredResourceDescriptors(ListOption...)]
+ public Page listMonitoredResourceDescriptors() {
+ // [START listMonitoredResourceDescriptors]
+ Page descriptors =
+ logging.listMonitoredResourceDescriptors(ListOption.pageSize(100));
+ for (MonitoredResourceDescriptor descriptor : descriptors.iterateAll()) {
+ // do something with the descriptor
+ }
+ // [END listMonitoredResourceDescriptors]
+ return descriptors;
+ }
+
+ /** Example of asynchronously listing monitored resource descriptors, specifying the page size. */
+ // [TARGET listMonitoredResourceDescriptorsAsync(ListOption...)]
+ public Page listMonitoredResourceDescriptorsAsync()
+ throws ExecutionException, InterruptedException {
+ // [START listMonitoredResourceDescriptorsAsync]
+ Future> future =
+ logging.listMonitoredResourceDescriptorsAsync(ListOption.pageSize(100));
+ // ...
+ AsyncPage descriptors = future.get();
+ for (MonitoredResourceDescriptor descriptor : descriptors.iterateAll()) {
+ // do something with the descriptor
+ }
+ // [END listMonitoredResourceDescriptorsAsync]
+ return descriptors;
+ }
+
+ /** Example of creating a metric for logs with severity higher or equal to ERROR. */
+ // [TARGET create(MetricInfo)]
+ // [VARIABLE "my_metric_name"]
+ public Metric createMetric(String metricName) {
+ // [START createMetric]
+ MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR");
+ Metric metric = logging.create(metricInfo);
+ // [END createMetric]
+ return metric;
+ }
+
+ /**
+ * Example of asynchronously creating a metric for logs with severity higher or equal to ERROR.
+ */
+ // [TARGET createAsync(MetricInfo)]
+ // [VARIABLE "my_metric_name"]
+ public Metric createMetricAsync(String metricName)
+ throws ExecutionException, InterruptedException {
+ // [START createMetricAsync]
+ MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR");
+ Future future = logging.createAsync(metricInfo);
+ // ...
+ Metric metric = future.get();
+ // [END createMetricAsync]
+ return metric;
+ }
+
+ /** Example of updating a metric. */
+ // [TARGET update(MetricInfo)]
+ // [VARIABLE "my_metric_name"]
+ public Metric updateMetric(String metricName) {
+ // [START updateMetric]
+ MetricInfo metricInfo =
+ MetricInfo.newBuilder(metricName, "severity>=ERROR")
+ .setDescription("new description")
+ .build();
+ Metric metric = logging.update(metricInfo);
+ // [END updateMetric]
+ return metric;
+ }
+
+ /** Example of asynchronously updating a metric. */
+ // [TARGET updateAsync(MetricInfo)]
+ // [VARIABLE "my_metric_name"]
+ public Metric updateMetricAsync(String metricName)
+ throws ExecutionException, InterruptedException {
+ // [START updateMetricAsync]
+ MetricInfo metricInfo =
+ MetricInfo.newBuilder(metricName, "severity>=ERROR")
+ .setDescription("new description")
+ .build();
+ Future future = logging.updateAsync(metricInfo);
+ // ...
+ Metric metric = future.get();
+ // [END updateMetricAsync]
+ return metric;
+ }
+
+ /** Example of getting a metric. */
+ // [TARGET getMetric(String)]
+ // [VARIABLE "my_metric_name"]
+ public Metric getMetric(String metricName) {
+ // [START getMetric]
+ Metric metric = logging.getMetric(metricName);
+ if (metric == null) {
+ // metric was not found
+ }
+ // [END getMetric]
+ return metric;
+ }
+
+ /** Example of asynchronously getting a metric. */
+ // [TARGET getMetricAsync(String)]
+ // [VARIABLE "my_metric_name"]
+ public Metric getMetricAsync(String metricName) throws ExecutionException, InterruptedException {
+ // [START getMetricAsync]
+ Future future = logging.getMetricAsync(metricName);
+ // ...
+ Metric metric = future.get();
+ if (metric == null) {
+ // metric was not found
+ }
+ // [END getMetricAsync]
+ return metric;
+ }
+
+ /** Example of listing metrics, specifying the page size. */
+ // [TARGET listMetrics(ListOption...)]
+ public Page listMetrics() {
+ // [START listMetrics]
+ Page metrics = logging.listMetrics(ListOption.pageSize(100));
+ for (Metric metric : metrics.iterateAll()) {
+ // do something with the metric
+ }
+ // [END listMetrics]
+ return metrics;
+ }
+
+ /** Example of asynchronously listing metrics, specifying the page size. */
+ // [TARGET listMetricsAsync(ListOption...)]
+ public Page listMetricsAsync() throws ExecutionException, InterruptedException {
+ // [START listMetricsAsync]
+ Future> future = logging.listMetricsAsync(ListOption.pageSize(100));
+ // ...
+ AsyncPage metrics = future.get();
+ for (Metric metric : metrics.iterateAll()) {
+ // do something with the metric
+ }
+ // [END listMetricsAsync]
+ return metrics;
+ }
+
+ /** Example of deleting a metric. */
+ // [TARGET deleteMetric(String)]
+ // [VARIABLE "my_metric_name"]
+ public boolean deleteMetric(String metricName) {
+ // [START deleteMetric]
+ boolean deleted = logging.deleteMetric(metricName);
+ if (deleted) {
+ // the metric was deleted
+ } else {
+ // the metric was not found
+ }
+ // [END deleteMetric]
+ return deleted;
+ }
+
+ /** Example of asynchronously deleting a metric. */
+ // [TARGET deleteMetricAsync(String)]
+ // [VARIABLE "my_metric_name"]
+ public boolean deleteMetricAsync(String metricName)
+ throws ExecutionException, InterruptedException {
+ // [START deleteMetricAsync]
+ Future future = logging.deleteMetricAsync(metricName);
+ // ...
+ boolean deleted = future.get();
+ if (deleted) {
+ // the metric was deleted
+ } else {
+ // the metric was not found
+ }
+ // [END deleteMetricAsync]
+ return deleted;
+ }
+
+ /**
+ * Example of writing log entries and providing a default log name and monitored resource. Logging
+ * writes are asynchronous by default. {@link Logging#setWriteSynchronicity(Synchronicity)} can be
+ * used to update the synchronicity.
+ */
+ // [TARGET write(Iterable, WriteOption...)]
+ // [VARIABLE "my_log_name"]
+ public void write(String logName) {
+ List entries = new ArrayList<>();
+ entries.add(LogEntry.of(StringPayload.of("Entry payload")));
+ Map jsonMap = new HashMap<>();
+ jsonMap.put("key", "value");
+ entries.add(LogEntry.of(JsonPayload.of(jsonMap)));
+ logging.write(
+ entries,
+ WriteOption.logName(logName),
+ WriteOption.resource(MonitoredResource.newBuilder("global").build()));
+ }
+
+ /** Example of listing log entries for a specific log. */
+ // [TARGET listLogEntries(EntryListOption...)]
+ // [VARIABLE "logName=projects/my_project_id/logs/my_log_name"]
+ public Page listLogEntries(String filter) {
+ Page entries = logging.listLogEntries(EntryListOption.filter(filter));
+ for (LogEntry entry : entries.iterateAll()) {
+ // do something with the entry
+ }
+ return entries;
+ }
+
+ /** Example of asynchronously listing log entries for a specific log. */
+ // [TARGET listLogEntriesAsync(EntryListOption...)]
+ // [VARIABLE "logName=projects/my_project_id/logs/my_log_name"]
+ public Page listLogEntriesAsync(String filter)
+ throws ExecutionException, InterruptedException {
+ // [START listLogEntriesAsync]
+ Future> future =
+ logging.listLogEntriesAsync(EntryListOption.filter(filter));
+ // ...
+ AsyncPage entries = future.get();
+ for (LogEntry entry : entries.iterateAll()) {
+ // do something with the entry
+ }
+ // [END listLogEntriesAsync]
+ return entries;
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/MetricSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/MetricSnippets.java
new file mode 100644
index 000000000000..2e0a9a2eab21
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/MetricSnippets.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in Metric's javadoc. Any change to this file should be reflected in
+ * Metric's javadoc.
+ */
+
+package com.google.cloud.examples.logging.snippets;
+
+import com.google.cloud.logging.Metric;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/** This class contains a number of snippets for the {@link Metric} class. */
+public class MetricSnippets {
+
+ private final Metric metric;
+
+ public MetricSnippets(Metric metric) {
+ this.metric = metric;
+ }
+
+ /** Example of getting the metric's latest information. */
+ // [TARGET reload()]
+ public Metric reload() {
+ // [START reload]
+ Metric latestMetric = metric.reload();
+ if (latestMetric == null) {
+ // the metric was not found
+ }
+ // [END reload]
+ return latestMetric;
+ }
+
+ /** Example of asynchronously getting the metric's latest information. */
+ // [TARGET reloadAsync()]
+ public Metric reloadAsync() throws ExecutionException, InterruptedException {
+ // [START reloadAsync]
+ Future future = metric.reloadAsync();
+ // ...
+ Metric latestMetric = future.get();
+ if (latestMetric == null) {
+ // the metric was not found
+ }
+ // [END reloadAsync]
+ return latestMetric;
+ }
+
+ /** Example of updating the metric's information. */
+ // [TARGET update()]
+ public Metric update() {
+ // [START update]
+ Metric updatedMetric =
+ metric.toBuilder().setDescription("A more detailed description").build().update();
+ // [END update]
+ return updatedMetric;
+ }
+
+ /** Example of asynchronously updating the metric's information. */
+ // [TARGET updateAsync()]
+ public Metric updateAsync() throws ExecutionException, InterruptedException {
+ // [START updateAsync]
+ Future future =
+ metric.toBuilder().setDescription("A more detailed description").build().updateAsync();
+ // ...
+ Metric updatedMetric = future.get();
+ // [END updateAsync]
+ return updatedMetric;
+ }
+
+ /** Example of deleting the metric. */
+ // [TARGET delete()]
+ public boolean delete() {
+ // [START delete]
+ boolean deleted = metric.delete();
+ if (deleted) {
+ // the metric was deleted
+ } else {
+ // the metric was not found
+ }
+ // [END delete]
+ return deleted;
+ }
+
+ /** Example of asynchronously deleting the metric. */
+ // [TARGET deleteAsync()]
+ public boolean deleteAsync() throws ExecutionException, InterruptedException {
+ // [START deleteAsync]
+ Future future = metric.deleteAsync();
+ // ...
+ boolean deleted = future.get();
+ if (deleted) {
+ // the metric was deleted
+ } else {
+ // the metric was not found
+ }
+ // [END deleteAsync]
+ return deleted;
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/SinkSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/SinkSnippets.java
new file mode 100644
index 000000000000..ea0f5de4649f
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/SinkSnippets.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in Sink's javadoc. Any change to this file should be reflected in Sink's
+ * javadoc.
+ */
+
+package com.google.cloud.examples.logging.snippets;
+
+import com.google.cloud.logging.Sink;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/** This class contains a number of snippets for the {@link Sink} class. */
+public class SinkSnippets {
+
+ private final Sink sink;
+
+ public SinkSnippets(Sink sink) {
+ this.sink = sink;
+ }
+
+ /** Example of getting the sink's latest information. */
+ // [TARGET reload()]
+ public Sink reload() {
+ // [START reload]
+ Sink latestSink = sink.reload();
+ if (latestSink == null) {
+ // the sink was not found
+ }
+ // [END reload]
+ return latestSink;
+ }
+
+ /** Example of asynchronously getting the sink's latest information. */
+ // [TARGET reloadAsync()]
+ public Sink reloadAsync() throws ExecutionException, InterruptedException {
+ // [START reloadAsync]
+ Future future = sink.reloadAsync();
+ // ...
+ Sink latestSink = future.get();
+ if (latestSink == null) {
+ // the sink was not found
+ }
+ // [END reloadAsync]
+ return latestSink;
+ }
+
+ /** Example of updating the sink's information. */
+ // [TARGET update()]
+ public Sink update() {
+ // [START update]
+ Sink updatedSink = sink.toBuilder().setFilter("severity<=ERROR").build().update();
+ // [END update]
+ return updatedSink;
+ }
+
+ /** Example of asynchronously updating the sink's information. */
+ // [TARGET updateAsync()]
+ public Sink updateAsync() throws ExecutionException, InterruptedException {
+ // [START updateAsync]
+ Future future = sink.toBuilder().setFilter("severity<=ERROR").build().updateAsync();
+ // ...
+ Sink updatedSink = future.get();
+ // [END updateAsync]
+ return updatedSink;
+ }
+
+ /** Example of deleting the sink. */
+ // [TARGET delete()]
+ public boolean delete() {
+ // [START delete]
+ boolean deleted = sink.delete();
+ if (deleted) {
+ // the sink was deleted
+ } else {
+ // the sink was not found
+ }
+ // [END delete]
+ return deleted;
+ }
+
+ /** Example of asynchronously deleting the sink. */
+ // [TARGET deleteAsync()]
+ public boolean deleteAsync() throws ExecutionException, InterruptedException {
+ // [START deleteAsync]
+ Future future = sink.deleteAsync();
+ // ...
+ boolean deleted = future.get();
+ if (deleted) {
+ // the sink was deleted
+ } else {
+ // the sink was not found
+ }
+ // [END deleteAsync]
+ return deleted;
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/WriteAndListLogEntries.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/WriteAndListLogEntries.java
new file mode 100644
index 000000000000..4db4f1e8525e
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/logging/snippets/WriteAndListLogEntries.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.logging.snippets;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.MonitoredResource;
+import com.google.cloud.logging.LogEntry;
+import com.google.cloud.logging.Logging;
+import com.google.cloud.logging.Logging.EntryListOption;
+import com.google.cloud.logging.LoggingOptions;
+import com.google.cloud.logging.Payload.StringPayload;
+import java.util.Collections;
+
+/**
+ * A snippet for Stackdriver Logging showing how to write a log entry. The snippet also shows how to
+ * list all log entries with a given log name.
+ *
+ * @see Sinks
+ */
+public class WriteAndListLogEntries {
+
+ public static void main(String... args) throws Exception {
+ // Create a service object
+ // Credentials are inferred from the environment
+ LoggingOptions options = LoggingOptions.getDefaultInstance();
+ try (Logging logging = options.getService()) {
+
+ // Create a log entry
+ LogEntry firstEntry =
+ LogEntry.newBuilder(StringPayload.of("message"))
+ .setLogName("test-log")
+ .setResource(
+ MonitoredResource.newBuilder("global")
+ .addLabel("project_id", options.getProjectId())
+ .build())
+ .build();
+ logging.write(Collections.singleton(firstEntry));
+
+ // List log entries
+ Page entries =
+ logging.listLogEntries(
+ EntryListOption.filter(
+ "logName=projects/" + options.getProjectId() + "/logs/test-log"));
+ for (LogEntry logEntry : entries.iterateAll()) {
+ System.out.println(logEntry);
+ }
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/CountBytes.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/CountBytes.java
new file mode 100644
index 000000000000..75ac7f1cf704
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/CountBytes.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.io.BaseEncoding;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * CountBytes will read through the whole file given as input.
+ *
+ *
This example shows how to read a file size using NIO. File.size returns the size of the file
+ * as saved in Storage metadata. This class also shows how to read all of the file's contents using
+ * NIO, computes a MD5 hash, and reports how long it took.
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
{@code target/appassembler/bin/CountBytes }
+ */
+public class CountBytes {
+
+ /** See the class documentation. */
+ public static void main(String[] args) throws IOException {
+ if (args.length == 0 || args[0].equals("--help")) {
+ help();
+ return;
+ }
+ for (String a : args) {
+ countFile(a);
+ }
+ }
+
+ /**
+ * Print the length of the indicated file.
+ *
+ *
This uses the normal Java NIO Api, so it can take advantage of any installed NIO Filesystem
+ * provider without any extra effort.
+ */
+ private static void countFile(String fname) {
+ // large buffers pay off
+ final int bufSize = 50 * 1024 * 1024;
+ try {
+ Path path = Paths.get(new URI(fname));
+ long size = Files.size(path);
+ System.out.println(fname + ": " + size + " bytes.");
+ ByteBuffer buf = ByteBuffer.allocate(bufSize);
+ System.out.println("Reading the whole file...");
+ Stopwatch sw = Stopwatch.createStarted();
+ try (SeekableByteChannel chan = Files.newByteChannel(path)) {
+ long total = 0;
+ int readCalls = 0;
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ while (chan.read(buf) > 0) {
+ readCalls++;
+ md.update(buf.array(), 0, buf.position());
+ total += buf.position();
+ buf.flip();
+ }
+ readCalls++; // We must count the last call
+ long elapsed = sw.elapsed(TimeUnit.SECONDS);
+ System.out.println(
+ "Read all "
+ + total
+ + " bytes in "
+ + elapsed
+ + "s. "
+ + "("
+ + readCalls
+ + " calls to chan.read)");
+ String hex = String.valueOf(BaseEncoding.base16().encode(md.digest()));
+ System.out.println("The MD5 is: 0x" + hex);
+ if (total != size) {
+ System.out.println(
+ "Wait, this doesn't match! We saw "
+ + total
+ + " bytes, "
+ + "yet the file size is listed at "
+ + size
+ + " bytes.");
+ }
+ }
+ } catch (Exception ex) {
+ System.out.println(fname + ": " + ex.toString());
+ }
+ }
+
+ private static void help() {
+ String[] help = {"The argument is a ", "and we show the length of that file."};
+ for (String s : help) {
+ System.out.println(s);
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/ParallelCountBytes.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/ParallelCountBytes.java
new file mode 100644
index 000000000000..820f922f7147
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/ParallelCountBytes.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.io.BaseEncoding;
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.util.ArrayDeque;
+import java.util.Queue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ParallelCountBytes will read through the whole file given as input.
+ *
+ *
This example shows how to go through all the contents of a file, in order, using multithreaded
+ * NIO reads. It prints a MD5 hash and reports how long it took.
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
+ */
+public class ParallelCountBytes {
+
+ /**
+ * WorkUnit holds a buffer and the instructions for what to put in it.
+ *
+ *
Use it like this:
+ *
+ *
+ *
call()
+ *
the data is now in buf, you can access it directly
+ *
if need more, call resetForIndex(...) and go back to the top.
+ *
else, call close()
+ *
+ */
+ private static class WorkUnit implements Callable, Closeable {
+ public final ByteBuffer buf;
+ final SeekableByteChannel chan;
+ final int blockSize;
+ int blockIndex;
+
+ public WorkUnit(SeekableByteChannel chan, int blockSize, int blockIndex) {
+ this.chan = chan;
+ this.buf = ByteBuffer.allocate(blockSize);
+ this.blockSize = blockSize;
+ this.blockIndex = blockIndex;
+ }
+
+ @Override
+ public WorkUnit call() throws IOException {
+ long pos = ((long) blockSize) * blockIndex;
+ if (pos > chan.size()) {
+ return this;
+ }
+ chan.position(pos);
+ // read until buffer is full, or EOF
+ while (chan.read(buf) > 0) {}
+ ;
+ return this;
+ }
+
+ public WorkUnit resetForIndex(int blockIndex) {
+ this.blockIndex = blockIndex;
+ buf.flip();
+ return this;
+ }
+
+ public void close() throws IOException {
+ chan.close();
+ }
+ }
+
+ /** See the class documentation. */
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0 || args[0].equals("--help")) {
+ help();
+ return;
+ }
+ for (String a : args) {
+ countFile(a);
+ }
+ }
+
+ /**
+ * Print the length and MD5 of the indicated file.
+ *
+ *
This uses the normal Java NIO Api, so it can take advantage of any installed NIO Filesystem
+ * provider without any extra effort.
+ */
+ private static void countFile(String fname) throws Exception {
+ // large buffers pay off
+ final int bufSize = 50 * 1024 * 1024;
+ Queue> work = new ArrayDeque<>();
+ Path path = Paths.get(new URI(fname));
+ long size = Files.size(path);
+ System.out.println(fname + ": " + size + " bytes.");
+ int nThreads = (int) Math.ceil(size / (double) bufSize);
+ if (nThreads > 4) nThreads = 4;
+ System.out.println("Reading the whole file using " + nThreads + " threads...");
+ Stopwatch sw = Stopwatch.createStarted();
+ long total = 0;
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ ExecutorService exec = Executors.newFixedThreadPool(nThreads);
+ int blockIndex;
+ for (blockIndex = 0; blockIndex < nThreads; blockIndex++) {
+ work.add(exec.submit(new WorkUnit(Files.newByteChannel(path), bufSize, blockIndex)));
+ }
+ while (!work.isEmpty()) {
+ WorkUnit full = work.remove().get();
+ md.update(full.buf.array(), 0, full.buf.position());
+ total += full.buf.position();
+ if (full.buf.hasRemaining()) {
+ full.close();
+ } else {
+ work.add(exec.submit(full.resetForIndex(blockIndex++)));
+ }
+ }
+ exec.shutdown();
+
+ long elapsed = sw.elapsed(TimeUnit.SECONDS);
+ System.out.println("Read all " + total + " bytes in " + elapsed + "s. ");
+ String hex = String.valueOf(BaseEncoding.base16().encode(md.digest()));
+ System.out.println("The MD5 is: 0x" + hex);
+ if (total != size) {
+ System.out.println(
+ "Wait, this doesn't match! We saw "
+ + total
+ + " bytes, "
+ + "yet the file size is listed at "
+ + size
+ + " bytes.");
+ }
+ }
+
+ private static void help() {
+ String[] help = {"The argument is a ", "and we show the length of that file."};
+ for (String s : help) {
+ System.out.println(s);
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/Stat.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/Stat.java
new file mode 100644
index 000000000000..e68b0ea1d877
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/Stat.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Stat is a super-simple program that just displays the size of the file passed as argument.
+ *
+ *
It's meant to be used to test Google Cloud's integration with Java NIO.
+ *
+ *
You can either use the '--check' argument to see whether Google Cloud Storage is enabled, or
+ * you can directly pass in a Google Cloud Storage file name to use. In that case you have to be
+ * logged in (using e.g. the gcloud auth command).
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
In short, this version (in google-cloud-examples) is in a package that lists google-cloud-nio
+ * as a dependency, so it will work directly without having to do any special work.
+ */
+public class Stat {
+
+ /** See the class documentation. */
+ public static void main(String[] args) throws IOException {
+ if (args.length == 0 || args[0].equals("--help")) {
+ help();
+ return;
+ }
+ if (args[0].equals("--list")) {
+ listFilesystems();
+ return;
+ }
+ if (args[0].equals("--check")) {
+ checkGcs();
+ return;
+ }
+ for (String a : args) {
+ statFile(a);
+ }
+ }
+
+ /**
+ * Print the length of the indicated file.
+ *
+ *
This uses the normal Java NIO Api, so it can take advantage of any installed NIO Filesystem
+ * provider without any extra effort.
+ */
+ private static void statFile(String fname) {
+ try {
+ Path path = Paths.get(new URI(fname));
+ long size = Files.size(path);
+ System.out.println(fname + ": " + size + " bytes.");
+ } catch (Exception ex) {
+ System.out.println(fname + ": " + ex.toString());
+ }
+ }
+
+ private static void help() {
+ String[] help = {
+ "The arguments can be one of:",
+ " * ",
+ " to display the length of that file.",
+ "",
+ " * --list",
+ " to list the filesystem providers.",
+ "",
+ " * --check",
+ " to double-check the Google Cloud Storage provider is installed.",
+ "",
+ "The purpose of this tool is to demonstrate that the Google Cloud NIO filesystem provider",
+ "can add Google Cloud Storage support to programs not explicitly designed for it.",
+ "",
+ "This tool normally knows nothing of Google Cloud Storage. If you pass it --check",
+ "or a Google Cloud Storage file name (e.g. gs://mybucket/myfile), it will show an error.",
+ "However, by just adding the google-cloud-nio jar as a dependency and recompiling, this",
+ "tool is made aware of gs:// paths and can access files on the cloud.",
+ "",
+ "The Google Cloud NIO filesystem provider can similarly enable existing Java 7 programs",
+ "to read and write cloud files, even if they have no special built-in cloud support."
+ };
+ for (String s : help) {
+ System.out.println(s);
+ }
+ }
+
+ private static void listFilesystems() {
+ System.out.println("Installed filesystem providers:");
+ for (FileSystemProvider p : FileSystemProvider.installedProviders()) {
+ System.out.println(" " + p.getScheme());
+ }
+ }
+
+ private static void checkGcs() {
+ FileSystem fs = FileSystems.getFileSystem(URI.create("gs://domain-registry-alpha"));
+ System.out.println("Success! We can instantiate a gs:// filesystem.");
+ System.out.println("isOpen: " + fs.isOpen());
+ System.out.println("isReadOnly: " + fs.isReadOnly());
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateCloudStorageFileSystem.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateCloudStorageFileSystem.java
new file mode 100644
index 000000000000..4990f0f10169
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateCloudStorageFileSystem.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import com.google.cloud.storage.contrib.nio.CloudStorageFileSystem;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/**
+ * A snippet for Google Cloud Storage NIO that shows how to create a {@link CloudStorageFileSystem}
+ * for a bucket. The snippet also shows how to create a file, given the file system.
+ */
+public class CreateCloudStorageFileSystem {
+
+ public static void main(String... args) throws IOException {
+ // Create a file system for the bucket
+ CloudStorageFileSystem fs = CloudStorageFileSystem.forBucket("bucket");
+ byte[] data = "hello world".getBytes(StandardCharsets.UTF_8);
+ Path path = fs.getPath("/object");
+ // Write a file in the bucket
+ Files.write(path, data);
+ // Read a file from the bucket
+ data = Files.readAllBytes(path);
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateInputStream.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateInputStream.java
new file mode 100644
index 000000000000..a67a5951b01e
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/CreateInputStream.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/** A snippet showing how to create an input stream for a Google Cloud Storage file using NIO. */
+public class CreateInputStream {
+
+ public static void main(String... args) throws IOException {
+ Path path = Paths.get(URI.create("gs://bucket/lolcat.csv"));
+ try (InputStream input = Files.newInputStream(path)) {
+ // use input stream
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/GetFileSystem.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/GetFileSystem.java
new file mode 100644
index 000000000000..579df65a6855
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/GetFileSystem.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+/**
+ * A snippet showing how to get a {@link FileSystem} instance for a Google Cloud Storage bucket.
+ * This snippet also shows how to create a file and read its lines.
+ */
+public class GetFileSystem {
+
+ public static void main(String... args) throws IOException {
+ FileSystem fs = FileSystems.getFileSystem(URI.create("gs://bucket"));
+ byte[] data = "hello world".getBytes(StandardCharsets.UTF_8);
+ Path path = fs.getPath("/object");
+ Files.write(path, data);
+ List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/ReadAllLines.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/ReadAllLines.java
new file mode 100644
index 000000000000..851706287dab
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/ReadAllLines.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+/** A snippet showing how to read all lines of a Google Cloud Storage file using NIO. */
+public class ReadAllLines {
+
+ public static void main(String... args) throws IOException {
+ Path path = Paths.get(URI.create("gs://bucket/lolcat.csv"));
+ List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/UseExplicitCredentials.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/UseExplicitCredentials.java
new file mode 100644
index 000000000000..62d08a5d1a19
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/UseExplicitCredentials.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import com.google.auth.oauth2.ServiceAccountCredentials;
+import com.google.cloud.storage.StorageOptions;
+import com.google.cloud.storage.contrib.nio.CloudStorageConfiguration;
+import com.google.cloud.storage.contrib.nio.CloudStorageFileSystem;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * A snippet for Google Cloud Storage NIO that shows how to create a {@link CloudStorageFileSystem}
+ * using explicitly-provided credentials instead of the default ones.
+ */
+public class UseExplicitCredentials {
+
+ public static void main(String... args) throws IOException {
+ // Create a file system for the bucket using the service account credentials
+ // saved in the file below.
+ String myCredentials = "/path/to/my/key.json";
+ CloudStorageFileSystem fs =
+ CloudStorageFileSystem.forBucket(
+ "mybucket",
+ CloudStorageConfiguration.DEFAULT,
+ StorageOptions.newBuilder()
+ .setCredentials(
+ ServiceAccountCredentials.fromStream(new FileInputStream(myCredentials)))
+ .build());
+ // Can now read and write to the bucket using fs
+ // (see e.g. ReadAllLines for an example).
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/WriteFileWithAttributes.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/WriteFileWithAttributes.java
new file mode 100644
index 000000000000..35121025c4af
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/nio/snippets/WriteFileWithAttributes.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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 com.google.cloud.examples.nio.snippets;
+
+import static com.google.cloud.storage.contrib.nio.CloudStorageOptions.withMimeType;
+import static com.google.cloud.storage.contrib.nio.CloudStorageOptions.withoutCaching;
+
+import com.google.cloud.storage.contrib.nio.CloudStorageOptions;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A snippet showing how to write a file to Google Cloud Storage using NIO. This example also shows
+ * how to set file attributes, using {@link CloudStorageOptions} static helpers.
+ */
+public class WriteFileWithAttributes {
+
+ private static final String[] LINES = {"value1,", "value"};
+
+ public static void main(String... args) throws IOException {
+ List csvLines = Arrays.asList(LINES);
+ Path path = Paths.get(URI.create("gs://bucket/lolcat.csv"));
+ Files.write(
+ path,
+ csvLines,
+ StandardCharsets.UTF_8,
+ withMimeType("text/csv; charset=UTF-8"),
+ withoutCaching());
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/UsePubSubEmulatorSnippet.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/UsePubSubEmulatorSnippet.java
new file mode 100644
index 000000000000..6838384aac1f
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/UsePubSubEmulatorSnippet.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * 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 com.google.cloud.examples.pubsub.snippets;
+
+import com.google.api.gax.core.CredentialsProvider;
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.GrpcTransportChannel;
+import com.google.api.gax.rpc.FixedTransportChannelProvider;
+import com.google.api.gax.rpc.TransportChannelProvider;
+import com.google.cloud.pubsub.v1.Publisher;
+import com.google.cloud.pubsub.v1.TopicAdminClient;
+import com.google.cloud.pubsub.v1.TopicAdminSettings;
+import com.google.pubsub.v1.TopicName;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import java.io.IOException;
+
+/**
+ * Snippet that demonstrates creating Pub/Sub clients using the Google Cloud Pub/Sub emulator.
+ *
+ *
Note: clients cannot start/stop the emulator.
+ */
+public class UsePubSubEmulatorSnippet {
+
+ public static void main(String... args) throws IOException {
+ // [START pubsub_use_emulator]
+ String hostport = System.getenv("PUBSUB_EMULATOR_HOST");
+ ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build();
+ try {
+ TransportChannelProvider channelProvider =
+ FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
+ CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
+
+ // Set the channel and credentials provider when creating a `TopicAdminClient`.
+ // Similarly for SubscriptionAdminClient
+ TopicAdminClient topicClient =
+ TopicAdminClient.create(
+ TopicAdminSettings.newBuilder()
+ .setTransportChannelProvider(channelProvider)
+ .setCredentialsProvider(credentialsProvider)
+ .build());
+
+ TopicName topicName = TopicName.of("my-project-id", "my-topic-id");
+ // Set the channel and credentials provider when creating a `Publisher`.
+ // Similarly for Subscriber
+ Publisher publisher =
+ Publisher.newBuilder(topicName)
+ .setChannelProvider(channelProvider)
+ .setCredentialsProvider(credentialsProvider)
+ .build();
+ } finally {
+ channel.shutdown();
+ }
+ // [END pubsub_use_emulator]
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java
new file mode 100644
index 000000000000..f6b43082fd8e
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * 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 com.google.cloud.examples.resourcemanager;
+
+import com.google.cloud.resourcemanager.Project;
+import com.google.cloud.resourcemanager.ProjectInfo;
+import com.google.cloud.resourcemanager.ResourceManager;
+import com.google.cloud.resourcemanager.ResourceManagerOptions;
+import com.google.common.base.Joiner;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * An example of using Google Cloud Resource Manager.
+ *
+ *
This example creates, deletes, gets, and lists projects.
+ *
+ *
See the
+ * README for compilation instructions. Run this code with
+ *
+ *
+ */
+public class ResourceManagerExample {
+
+ private static final String DEFAULT_ACTION = "list";
+ private static final Map ACTIONS = new HashMap<>();
+
+ private interface ResourceManagerAction {
+ void run(ResourceManager resourceManager, String... args);
+
+ String[] getRequiredParams();
+
+ String[] getOptionalParams();
+ }
+
+ private static class CreateAction implements ResourceManagerAction {
+ @Override
+ public void run(ResourceManager resourceManager, String... args) {
+ String projectId = args[0];
+ Map labels = new HashMap<>();
+ for (int i = 1; i < args.length; i += 2) {
+ if (i + 1 < args.length) {
+ labels.put(args[i], args[i + 1]);
+ } else {
+ labels.put(args[i], "");
+ }
+ }
+ Project project =
+ resourceManager.create(ProjectInfo.newBuilder(projectId).setLabels(labels).build());
+ System.out.printf(
+ "Successfully created project '%s': %s.%n", projectId, projectDetails(project));
+ }
+
+ @Override
+ public String[] getRequiredParams() {
+ return new String[] {"project-id"};
+ }
+
+ @Override
+ public String[] getOptionalParams() {
+ return new String[] {"label-key-1", "label-value-1", "label-key-2", "label-value-2", "..."};
+ }
+ }
+
+ private static class DeleteAction implements ResourceManagerAction {
+ @Override
+ public void run(ResourceManager resourceManager, String... args) {
+ String projectId = args[0];
+ System.out.printf("Going to delete project \"%s\". Are you sure [y/N]: ", projectId);
+ Scanner scanner = new Scanner(System.in);
+ if (scanner.nextLine().toLowerCase().equals("y")) {
+ resourceManager.delete(projectId);
+ System.out.printf("Successfully deleted project %s.%n", projectId);
+ } else {
+ System.out.printf("Will not delete project %s.%n", projectId);
+ }
+ scanner.close();
+ }
+
+ @Override
+ public String[] getRequiredParams() {
+ return new String[] {"project-id"};
+ }
+
+ @Override
+ public String[] getOptionalParams() {
+ return new String[] {};
+ }
+ }
+
+ private static class GetAction implements ResourceManagerAction {
+ @Override
+ public void run(ResourceManager resourceManager, String... args) {
+ String projectId = args[0];
+ ProjectInfo project = resourceManager.get(projectId);
+ if (project != null) {
+ System.out.printf(
+ "Successfully got project '%s': %s.%n", projectId, projectDetails(project));
+ } else {
+ System.out.printf("Could not find project '%s'.%n", projectId);
+ }
+ }
+
+ @Override
+ public String[] getRequiredParams() {
+ return new String[] {"project-id"};
+ }
+
+ @Override
+ public String[] getOptionalParams() {
+ return new String[] {};
+ }
+ }
+
+ private static class ListAction implements ResourceManagerAction {
+ @Override
+ public void run(ResourceManager resourceManager, String... args) {
+ System.out.println("Projects you can view:");
+ for (ProjectInfo project : resourceManager.list().getValues()) {
+ System.out.println(projectDetails(project));
+ }
+ }
+
+ @Override
+ public String[] getRequiredParams() {
+ return new String[] {};
+ }
+
+ @Override
+ public String[] getOptionalParams() {
+ return new String[] {};
+ }
+ }
+
+ static {
+ ACTIONS.put("create", new CreateAction());
+ ACTIONS.put("delete", new DeleteAction());
+ ACTIONS.put("get", new GetAction());
+ ACTIONS.put("list", new ListAction());
+ }
+
+ private static String projectDetails(ProjectInfo project) {
+ return new StringBuilder()
+ .append("{projectId:")
+ .append(project.getProjectId())
+ .append(", projectNumber:")
+ .append(project.getProjectNumber())
+ .append(", createTimeMillis:")
+ .append(project.getCreateTimeMillis())
+ .append(", state:")
+ .append(project.getState())
+ .append(", labels:")
+ .append(project.getLabels())
+ .append("}")
+ .toString();
+ }
+
+ private static void addUsage(
+ String actionName, ResourceManagerAction action, StringBuilder usage) {
+ usage.append(actionName);
+ Joiner joiner = Joiner.on(" ");
+ String[] requiredParams = action.getRequiredParams();
+ if (requiredParams.length > 0) {
+ usage.append(' ');
+ joiner.appendTo(usage, requiredParams);
+ }
+ String[] optionalParams = action.getOptionalParams();
+ if (optionalParams.length > 0) {
+ usage.append(" [");
+ joiner.appendTo(usage, optionalParams);
+ usage.append(']');
+ }
+ }
+
+ public static void main(String... args) {
+ String actionName = args.length > 0 ? args[0].toLowerCase() : DEFAULT_ACTION;
+ ResourceManagerAction action = ACTIONS.get(actionName);
+ if (action == null) {
+ StringBuilder actionAndParams = new StringBuilder();
+ for (Map.Entry entry : ACTIONS.entrySet()) {
+ addUsage(entry.getKey(), entry.getValue(), actionAndParams);
+ actionAndParams.append('|');
+ }
+ actionAndParams.setLength(actionAndParams.length() - 1);
+ System.out.printf(
+ "Usage: %s [%s]%n", ResourceManagerExample.class.getSimpleName(), actionAndParams);
+ return;
+ }
+
+ // If you want to access a local Resource Manager emulator (after creating and starting the
+ // LocalResourceManagerHelper), use the following code instead:
+ // ResourceManager resourceManager = LocalResourceManagerHelper.getOptions().getService();
+ ResourceManager resourceManager = ResourceManagerOptions.getDefaultInstance().getService();
+ args = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[] {};
+ if (args.length < action.getRequiredParams().length) {
+ StringBuilder usage = new StringBuilder();
+ usage.append("Usage: ");
+ addUsage(actionName, action, usage);
+ System.out.println(usage);
+ } else {
+ action.run(resourceManager, args);
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java
new file mode 100644
index 000000000000..3727b6a1aeea
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in READMEs and javadoc. Any change to this file should be reflected in
+ * the project's READMEs and package-info.java.
+ */
+
+package com.google.cloud.examples.resourcemanager.snippets;
+
+import com.google.cloud.resourcemanager.Project;
+import com.google.cloud.resourcemanager.ProjectInfo;
+import com.google.cloud.resourcemanager.ResourceManager;
+import com.google.cloud.resourcemanager.ResourceManagerOptions;
+
+/**
+ * A snippet for Google Cloud Resource Manager showing how to create a project if it does not exist.
+ */
+public class GetOrCreateProject {
+
+ public static void main(String... args) {
+ // Create Resource Manager service object.
+ // By default, credentials are inferred from the runtime environment.
+ ResourceManager resourceManager = ResourceManagerOptions.getDefaultInstance().getService();
+
+ String projectId = "my-globally-unique-project-id"; // Change to a unique project ID.
+ // Get a project from the server.
+ Project project = resourceManager.get(projectId);
+ if (project == null) {
+ // Create a project.
+ project = resourceManager.create(ProjectInfo.newBuilder(projectId).build());
+ }
+ System.out.println("Got project " + project.getProjectId() + " from the server.");
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java
new file mode 100644
index 000000000000..0b2347b62658
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in READMEs and javadoc. Any change to this file should be reflected in
+ * the project's READMEs and package-info.java.
+ */
+
+package com.google.cloud.examples.resourcemanager.snippets;
+
+import com.google.cloud.Identity;
+import com.google.cloud.Policy;
+import com.google.cloud.Role;
+import com.google.cloud.resourcemanager.Project;
+import com.google.cloud.resourcemanager.ResourceManager;
+import com.google.cloud.resourcemanager.ResourceManagerOptions;
+
+/** A snippet for Google Cloud Resource Manager showing how to modify a project's IAM policy. */
+public class ModifyPolicy {
+
+ public static void main(String... args) {
+ // Create Resource Manager service object
+ // By default, credentials are inferred from the runtime environment.
+ ResourceManager resourceManager = ResourceManagerOptions.getDefaultInstance().getService();
+
+ // Get a project from the server
+ String projectId = "some-project-id"; // Use an existing project's ID
+ Project project = resourceManager.get(projectId);
+
+ // Get the project's policy
+ Policy policy = project.getPolicy();
+
+ // Add a viewer
+ Policy.Builder modifiedPolicy = policy.toBuilder();
+ Identity newViewer = Identity.user("");
+ modifiedPolicy.addIdentity(Role.viewer(), newViewer);
+
+ // Write policy
+ Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build());
+
+ // Print policy
+ System.out.printf("Updated policy for %s: %n%s%n", projectId, updatedPolicy);
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java
new file mode 100644
index 000000000000..76b6b5e9f74b
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * 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.
+ */
+
+/*
+ * EDITING INSTRUCTIONS
+ * This file is referenced in READMEs and javadoc. Any change to this file should be reflected in
+ * the project's READMEs and package-info.java.
+ */
+
+package com.google.cloud.examples.resourcemanager.snippets;
+
+import com.google.cloud.resourcemanager.Project;
+import com.google.cloud.resourcemanager.ResourceManager;
+import com.google.cloud.resourcemanager.ResourceManagerOptions;
+
+/**
+ * A snippet for Google Cloud Resource Manager showing how to update a project and list all projects
+ * the user has permission to view.
+ */
+public class UpdateAndListProjects {
+
+ public static void main(String... args) {
+ // Create Resource Manager service object
+ // By default, credentials are inferred from the runtime environment.
+ ResourceManager resourceManager = ResourceManagerOptions.getDefaultInstance().getService();
+
+ // Get a project from the server
+ Project project = resourceManager.get("some-project-id"); // Use an existing project's ID
+
+ // Update a project
+ if (project != null) {
+ Project newProject =
+ project.toBuilder().addLabel("launch-status", "in-development").build().replace();
+ System.out.println(
+ "Updated the labels of project "
+ + newProject.getProjectId()
+ + " to be "
+ + newProject.getLabels());
+ }
+
+ // List all the projects you have permission to view.
+ System.out.println("Projects I can view:");
+ for (Project currentProject : resourceManager.list().iterateAll()) {
+ System.out.println(currentProject.getProjectId());
+ }
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/AssetSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/AssetSnippets.java
new file mode 100644
index 000000000000..d101ae186c0b
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/AssetSnippets.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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
+ *
+ * https://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 com.google.cloud.examples.securitycenter.snippets;
+
+import com.google.api.gax.longrunning.OperationFuture;
+import com.google.api.gax.rpc.ResourceExhaustedException;
+import com.google.cloud.securitycenter.v1.GroupAssetsRequest;
+import com.google.cloud.securitycenter.v1.GroupResult;
+import com.google.cloud.securitycenter.v1.ListAssetsRequest;
+import com.google.cloud.securitycenter.v1.ListAssetsResponse.ListAssetsResult;
+import com.google.cloud.securitycenter.v1.OrganizationName;
+import com.google.cloud.securitycenter.v1.RunAssetDiscoveryResponse;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.GroupAssetsPagedResponse;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListAssetsPagedResponse;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.Empty;
+import java.io.IOException;
+import org.threeten.bp.Duration;
+import org.threeten.bp.Instant;
+
+/** Snippets for how to work with Assets in Cloud Security Command Center. */
+public class AssetSnippets {
+ private AssetSnippets() {}
+
+ /**
+ * Lists all assets for an organization.
+ *
+ * @param organizationName The organization to list assets for.
+ */
+ // [START securitycenter_list_all_assets]
+ static ImmutableList listAssets(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to search for all assets in an organization.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ ListAssetsRequest.Builder request =
+ ListAssetsRequest.newBuilder().setParent(organizationName.toString());
+
+ // Call the API.
+ ListAssetsPagedResponse response = client.listAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them incrementally by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("All assets:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_all_assets]
+
+ /**
+ * Lists all project assets for an organization.
+ *
+ * @param organizationName The organization to list assets for.
+ */
+ // [START securitycenter_list_assets_with_filter]
+ static ImmutableList listAssetsWithFilter(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to search for all assets in an organization.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ ListAssetsRequest.Builder request =
+ ListAssetsRequest.newBuilder()
+ .setParent(organizationName.toString())
+ .setFilter(
+ "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");
+
+ // Call the API.
+ ListAssetsPagedResponse response = client.listAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them incrementally by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Project assets:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_assets_with_filter]
+
+ /**
+ * Lists all project assets for an organization at a given point in time.
+ *
+ * @param organizationName The organization to list assets for.
+ * @param asOf The snapshot time to query for assets. If null defaults to one day ago.
+ */
+ // [START securitycenter_list_assets_at_time]
+ static ImmutableList listAssetsAsOfYesterday(
+ OrganizationName organizationName, Instant asOf) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to search for all assets in an organization.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+
+ // Initialize the builder with the organization and filter
+ ListAssetsRequest.Builder request =
+ ListAssetsRequest.newBuilder()
+ .setParent(organizationName.toString())
+ .setFilter(
+ "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");
+
+ // Set read time to either the instant passed in or one day ago.
+ asOf = MoreObjects.firstNonNull(asOf, Instant.now().minus(Duration.ofDays(1)));
+ request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());
+
+ // Call the API.
+ ListAssetsPagedResponse response = client.listAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them incrementally by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Projects:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_assets_at_time]
+
+ /**
+ * Returns Assets and metadata about assets activity (e.g. added, removed, no change) between
+ * between asOf.minus(timespan) and asOf.
+ *
+ * @param timeSpan The time-range to compare assets over.
+ * @param asOf The instant in time to query for. If null, current time is assumed.
+ */
+ // [START securitycenter_list_assets_and_changes]
+ static ImmutableList listAssetAndStatusChanges(
+ OrganizationName organizationName, Duration timeSpan, Instant asOf) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+
+ // Start setting up a request for to search for all assets in an organization.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ ListAssetsRequest.Builder request =
+ ListAssetsRequest.newBuilder()
+ .setParent(organizationName.toString())
+ .setFilter(
+ "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");
+ request
+ .getCompareDurationBuilder()
+ .setSeconds(timeSpan.getSeconds())
+ .setNanos(timeSpan.getNano());
+
+ // Set read time to either the instant passed in or now.
+ asOf = MoreObjects.firstNonNull(asOf, Instant.now());
+ request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());
+
+ // Call the API.
+ ListAssetsPagedResponse response = client.listAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them incrementally by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Projects:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_assets_and_changes]
+
+ /**
+ * Groups all assets by their specified properties (e.g. type) for an organization.
+ *
+ * @param organizationName The organization to group assets for.
+ */
+ // [START securitycenter_group_all_assets]
+ static ImmutableList groupAssets(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to group all assets by type in an organization.
+ // OrganizationName organizationName = OrganizationName.of("123234324");
+ GroupAssetsRequest.Builder request =
+ GroupAssetsRequest.newBuilder()
+ .setGroupBy("security_center_properties.resource_type")
+ .setParent(organizationName.toString());
+
+ // Call the API.
+ GroupAssetsPagedResponse response = client.groupAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("All assets:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_all_assets]
+
+ /**
+ * Filters all assets by their specified properties and groups them by specified properties for an
+ * organization.
+ *
+ * @param organizationName The organization to group assets for.
+ */
+ // [START securitycenter_group_all_assets_with_filter]
+ static ImmutableList groupAssetsWithFilter(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to filter all assets by type and group them by project in an
+ // organization.
+ // OrganizationName organizationName = OrganizationName.of("123234324");
+ GroupAssetsRequest.Builder request =
+ GroupAssetsRequest.newBuilder()
+ .setFilter(
+ "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"")
+ .setGroupBy("security_center_properties.resource_project")
+ .setParent(organizationName.toString());
+
+ // Call the API.
+ GroupAssetsPagedResponse response = client.groupAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("All assets:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_all_assets_with_filter]
+
+ /**
+ * Groups all assets by their state_changes (ADDED/DELETED/ACTIVE) during a period of time for an
+ * organization.
+ *
+ * @param organizationName The organization to group assets for.
+ */
+ // [START securitycenter_group_all_assets_with_compare_duration]
+ static ImmutableList groupAssetsWithCompareDuration(
+ OrganizationName organizationName, Duration duration) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to group all assets during a period of time in an
+ // organization.
+ // OrganizationName organizationName = OrganizationName.of("123234324");
+ GroupAssetsRequest.Builder request =
+ GroupAssetsRequest.newBuilder()
+ .setGroupBy("state_change")
+ .setParent(organizationName.toString());
+ request
+ .getCompareDurationBuilder()
+ .setSeconds(duration.getSeconds())
+ .setNanos(duration.getNano());
+
+ // Call the API.
+ GroupAssetsPagedResponse response = client.groupAssets(request.build());
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("All assets:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_all_assets_with_compare_duration]
+
+ // [START securitycenter_run_asset_discovery]
+ static void runAssetDiscovery(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Call the API. Note calls to runAssetDiscovery are throttled if too many requests
+ // are made.
+ OperationFuture result =
+ client.runAssetDiscoveryAsync(organizationName);
+
+ // Uncomment this line to wait for a certain amount of time for the asset discovery run
+ // to complete.
+ // result.get(130, TimeUnit.SECONDS);
+ System.out.println("Asset discovery runs asynchronously.");
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ } catch (ResourceExhaustedException e) {
+ System.out.println("Asset discovery run already in progress.");
+ }
+ }
+ // [END securitycenter_run_asset_discovery]
+
+ public static void main(String... args) {
+ String org_id = System.getenv("ORGANIZATION_ID");
+ if (args.length > 0) {
+ org_id = args[0];
+ }
+
+ Preconditions.checkNotNull(
+ org_id,
+ "Organization ID must either be set in the environment variable \"ORGANIZATION_ID\" or passed"
+ + " as the first parameter to the program.");
+
+ listAssetsWithFilter(OrganizationName.of(org_id));
+ }
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/FindingSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/FindingSnippets.java
new file mode 100644
index 000000000000..9cf8cd4c9e99
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/FindingSnippets.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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
+ *
+ * https://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 com.google.cloud.examples.securitycenter.snippets;
+
+import com.google.cloud.securitycenter.v1.Finding;
+import com.google.cloud.securitycenter.v1.Finding.State;
+import com.google.cloud.securitycenter.v1.FindingName;
+import com.google.cloud.securitycenter.v1.GroupFindingsRequest;
+import com.google.cloud.securitycenter.v1.GroupResult;
+import com.google.cloud.securitycenter.v1.ListFindingsRequest;
+import com.google.cloud.securitycenter.v1.ListFindingsResponse.ListFindingsResult;
+import com.google.cloud.securitycenter.v1.OrganizationName;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.GroupFindingsPagedResponse;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListFindingsPagedResponse;
+import com.google.cloud.securitycenter.v1.SourceName;
+import com.google.cloud.securitycenter.v1.UpdateFindingRequest;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.iam.v1.TestIamPermissionsResponse;
+import com.google.protobuf.FieldMask;
+import com.google.protobuf.Timestamp;
+import com.google.protobuf.Value;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.threeten.bp.Duration;
+import org.threeten.bp.Instant;
+
+/** Snippets for how to work with Findings in Cloud Security Command Center. */
+public class FindingSnippets {
+ private FindingSnippets() {}
+
+ /**
+ * Create a finding under a source.
+ *
+ * @param sourceName The source for the finding.
+ */
+ // [START securitycenter_create_finding]
+ static Finding createFinding(SourceName sourceName, String findingId) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+ // String findingId = "samplefindingid";
+
+ // Use the current time as the finding "event time".
+ Instant eventTime = Instant.now();
+
+ // The resource this finding applies to. The CSCC UI can link
+ // the findings for a resource to the corresponding Asset of a resource
+ // if there are matches.
+ String resourceName = "//cloudresourcemanager.googleapis.com/organizations/11232";
+
+ // Start setting up a request to create a finding in a source.
+ Finding finding =
+ Finding.newBuilder()
+ .setParent(sourceName.toString())
+ .setState(State.ACTIVE)
+ .setResourceName(resourceName)
+ .setEventTime(
+ Timestamp.newBuilder()
+ .setSeconds(eventTime.getEpochSecond())
+ .setNanos(eventTime.getNano()))
+ .setCategory("MEDIUM_RISK_ONE")
+ .build();
+
+ // Call the API.
+ Finding response = client.createFinding(sourceName, findingId, finding);
+
+ System.out.println("Created Finding: " + response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_create_finding]
+
+ /**
+ * Create a finding with source properties under a source.
+ *
+ * @param sourceName The source for the finding.
+ */
+ // [START securitycenter_create_finding_with_source_properties]
+ static Finding createFindingWithSourceProperties(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ // Use the current time as the finding "event time".
+ Instant eventTime = Instant.now();
+
+ // Controlled by caller.
+ String findingId = "samplefindingid2";
+
+ // The resource this finding applies to. The CSCC UI can link
+ // the findings for a resource to the corresponding Asset of a resource
+ // if there are matches.
+ String resourceName = "//cloudresourcemanager.googleapis.com/organizations/11232";
+
+ // Define source properties values as protobuf "Value" objects.
+ Value stringValue = Value.newBuilder().setStringValue("stringExample").build();
+ Value numValue = Value.newBuilder().setNumberValue(1234).build();
+ ImmutableMap sourceProperties =
+ ImmutableMap.of("stringKey", stringValue, "numKey", numValue);
+
+ // Start setting up a request to create a finding in a source.
+ Finding finding =
+ Finding.newBuilder()
+ .setParent(sourceName.toString())
+ .setState(State.ACTIVE)
+ .setResourceName(resourceName)
+ .setEventTime(
+ Timestamp.newBuilder()
+ .setSeconds(eventTime.getEpochSecond())
+ .setNanos(eventTime.getNano()))
+ .putAllSourceProperties(sourceProperties)
+ .build();
+
+ // Call the API.
+ Finding response = client.createFinding(sourceName, findingId, finding);
+
+ System.out.println("Created Finding with Source Properties: " + response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_create_finding_with_source_properties]
+
+ /**
+ * Update a finding's source properties.
+ *
+ * @param findingName The finding to update.
+ */
+ // [START securitycenter_update_finding_source_properties]
+ static Finding updateFinding(FindingName findingName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // FindingName findingName = FindingName.of(/*organization=*/"123234324",
+ // /*source=*/"423432321", /*findingId=*/"samplefindingid2");
+
+ // Use the current time as the finding "event time".
+ Instant eventTime = Instant.now();
+
+ // Define source properties values as protobuf "Value" objects.
+ Value stringValue = Value.newBuilder().setStringValue("value").build();
+
+ FieldMask updateMask =
+ FieldMask.newBuilder()
+ .addPaths("event_time")
+ .addPaths("source_properties.stringKey")
+ .build();
+
+ Finding finding =
+ Finding.newBuilder()
+ .setName(findingName.toString())
+ .setEventTime(
+ Timestamp.newBuilder()
+ .setSeconds(eventTime.getEpochSecond())
+ .setNanos(eventTime.getNano()))
+ .putSourceProperties("stringKey", stringValue)
+ .build();
+
+ UpdateFindingRequest.Builder request =
+ UpdateFindingRequest.newBuilder().setFinding(finding).setUpdateMask(updateMask);
+
+ // Call the API.
+ Finding response = client.updateFinding(request.build());
+
+ System.out.println("Updated Finding: " + response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_update_finding_source_properties]
+
+ /**
+ * Updates a finding's state to INACTIVE.
+ *
+ * @param findingName The finding to update.
+ */
+ // [START securitycenter_update_finding_state]
+ static Finding setFindingState(FindingName findingName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // FindingName findingName = FindingName.of(/*organization=*/"123234324",
+ // /*source=*/"423432321", /*findingId=*/"samplefindingid2");
+
+ // Use the current time as the finding "event time".
+ Instant eventTime = Instant.now();
+
+ Finding response =
+ client.setFindingState(
+ findingName,
+ State.INACTIVE,
+ Timestamp.newBuilder()
+ .setSeconds(eventTime.getEpochSecond())
+ .setNanos(eventTime.getNano())
+ .build());
+
+ System.out.println("Updated Finding: " + response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_update_finding_state]
+
+ /**
+ * List all findings under an organization.
+ *
+ * @param organizationName The source to list all findings for.
+ */
+ // [START securitycenter_list_all_findings]
+ static ImmutableList listAllFindings(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ // "-" Indicates listing across all sources.
+ SourceName sourceName = SourceName.of(organizationName.getOrganization(), "-");
+
+ ListFindingsRequest.Builder request =
+ ListFindingsRequest.newBuilder().setParent(sourceName.toString());
+
+ // Call the API.
+ ListFindingsPagedResponse response = client.listFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings this can cause out of memory issues. You can process them in incrementally
+ // by returning the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_all_findings]
+
+ /**
+ * List filtered findings under a source.
+ *
+ * @param sourceName The source to list filtered findings for.
+ */
+ // [START securitycenter_list_filtered_findings]
+ static ImmutableList listFilteredFindings(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organizationId=*/"123234324",
+ // /*sourceId=*/"423432321");
+
+ // Create filter to category of MEDIUM_RISK_ONE
+ String filter = "category=\"MEDIUM_RISK_ONE\"";
+
+ ListFindingsRequest.Builder request =
+ ListFindingsRequest.newBuilder().setParent(sourceName.toString()).setFilter(filter);
+
+ // Call the API.
+ ListFindingsPagedResponse response = client.listFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings this can cause out of memory issues. You can process them in incrementally
+ // by returning the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_filtered_findings]
+
+ /**
+ * List findings at a specific time under a source.
+ *
+ * @param sourceName The source to list findings at a specific time for.
+ */
+ // [START securitycenter_list_findings_at_time]
+ static ImmutableList listFindingsAtTime(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organizationId=*/"123234324",
+ // /*sourceId=*/"423432321");
+
+ // 5 days ago
+ Instant fiveDaysAgo = Instant.now().minus(Duration.ofDays(5));
+
+ ListFindingsRequest.Builder request =
+ ListFindingsRequest.newBuilder()
+ .setParent(sourceName.toString())
+ .setReadTime(
+ Timestamp.newBuilder()
+ .setSeconds(fiveDaysAgo.getEpochSecond())
+ .setNanos(fiveDaysAgo.getNano()));
+
+ // Call the API.
+ ListFindingsPagedResponse response = client.listFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings this can cause out of memory issues. You can process them in incrementally
+ // by returning the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_findings_at_time]
+
+ /**
+ * Demonstrate calling testIamPermissions to determin if the service account has the correct
+ * permissions.
+ *
+ * @param sourceName The source to create a finding for.
+ */
+ // [START securitycenter_test_iam]
+ static TestIamPermissionsResponse testIamPermissions(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organizationId=*/"123234324",
+ // /*sourceId=*/"423432321");
+
+ // Iam permission to test.
+ List permissionsToTest = new ArrayList<>();
+ permissionsToTest.add("securitycenter.findings.update");
+
+ // Call the API.
+ TestIamPermissionsResponse response =
+ client.testIamPermissions(sourceName.toString(), permissionsToTest);
+ System.out.println("IAM Permission:");
+ System.out.println(response);
+
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_test_iam]
+
+ /**
+ * Group all findings under an organization across all sources by their specified properties (e.g.
+ * category).
+ *
+ * @param organizationName The organizatoin to group all findings for.
+ */
+ // [START securitycenter_group_all_findings]
+ static ImmutableList groupFindings(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // OrganizationName organizationName = OrganizationName.of("123234324");
+ SourceName sourceName = SourceName.of(organizationName.getOrganization(), "-");
+
+ GroupFindingsRequest.Builder request =
+ GroupFindingsRequest.newBuilder().setParent(sourceName.toString()).setGroupBy("category");
+
+ // Call the API.
+ GroupFindingsPagedResponse response = client.groupFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_all_findings]
+
+ /**
+ * Group findings under an organization and a source by their specified properties (e.g.
+ * category).
+ *
+ * @param sourceName The source to limit the findings to.
+ */
+ // [START securitycenter_group_findings_with_source]
+ static ImmutableList groupFindingsWithSource(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ GroupFindingsRequest.Builder request =
+ GroupFindingsRequest.newBuilder().setParent(sourceName.toString()).setGroupBy("category");
+
+ // Call the API.
+ GroupFindingsPagedResponse response = client.groupFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_findings_with_source]
+
+ /**
+ * Group active findings under an organization and a source by their specified properties (e.g.
+ * category).
+ *
+ * @param sourceName The source to limit the findings to.
+ */
+ // [START securitycenter_group_active_findings_with_source]
+ static ImmutableList groupActiveFindingsWithSource(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ GroupFindingsRequest.Builder request =
+ GroupFindingsRequest.newBuilder()
+ .setParent(sourceName.toString())
+ .setGroupBy("category")
+ .setFilter("state=\"ACTIVE\"");
+
+ // Call the API.
+ GroupFindingsPagedResponse response = client.groupFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_active_findings_with_source]
+
+ /**
+ * Group active findings under an organization and a source by their specified properties (e.g.
+ * category) at a specified time.
+ *
+ * @param sourceName The source to limit the findings to.
+ */
+ // [START securitycenter_group_active_findings_with_source_at_time]
+ static ImmutableList groupActiveFindingsWithSourceAtTime(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ // 1 day ago
+ Instant oneDayAgo = Instant.now().minusSeconds(60 * 60 * 24);
+
+ GroupFindingsRequest.Builder request =
+ GroupFindingsRequest.newBuilder()
+ .setParent(sourceName.toString())
+ .setGroupBy("category")
+ .setFilter("state=\"ACTIVE\"")
+ .setReadTime(
+ Timestamp.newBuilder()
+ .setSeconds(oneDayAgo.getEpochSecond())
+ .setNanos(oneDayAgo.getNano()));
+
+ // Call the API.
+ GroupFindingsPagedResponse response = client.groupFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_active_findings_with_source_at_time]
+
+ /**
+ * Group active findings under an organization and a source by their state_changes
+ * (ADDED/CHANGED/UNCHANGED) during a period.
+ *
+ * @param sourceName The source to limit the findings to.
+ */
+ // [START securitycenter_group_active_findings_with_source_and_compare_duration]
+ static ImmutableList groupActiveFindingsWithSourceAndCompareDuration(
+ SourceName sourceName, Duration duration) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ GroupFindingsRequest.Builder request =
+ GroupFindingsRequest.newBuilder()
+ .setParent(sourceName.toString())
+ .setGroupBy("state_change")
+ .setFilter("state=\"ACTIVE\"");
+ request
+ .getCompareDurationBuilder()
+ .setSeconds(duration.getSeconds())
+ .setNanos(duration.getNano());
+
+ // Call the API.
+ GroupFindingsPagedResponse response = client.groupFindings(request.build());
+
+ // This creates one list for all findings. If your organization has a large number of
+ // findings
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_group_active_findings_with_source_and_compare_duration]
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/OrganizationSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/OrganizationSnippets.java
new file mode 100644
index 000000000000..ca45abfe2334
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/OrganizationSnippets.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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
+ *
+ * https://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 com.google.cloud.examples.securitycenter.snippets;
+
+import com.google.cloud.securitycenter.v1.GetOrganizationSettingsRequest;
+import com.google.cloud.securitycenter.v1.OrganizationName;
+import com.google.cloud.securitycenter.v1.OrganizationSettings;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient;
+import com.google.cloud.securitycenter.v1.UpdateOrganizationSettingsRequest;
+import com.google.protobuf.FieldMask;
+import java.io.IOException;
+
+/** Snippets for how to work with Organizations in Cloud Security Command Center. */
+public class OrganizationSnippets {
+
+ private OrganizationSnippets() {}
+
+ /**
+ * Gets current settings for an organization.
+ *
+ * @param organizationName The organization to get settings for.
+ */
+ // [START securitycenter_get_org_settings]
+ static OrganizationSettings getOrganizationSettings(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to get OrganizationSettings for.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ GetOrganizationSettingsRequest.Builder request =
+ GetOrganizationSettingsRequest.newBuilder()
+ .setName(organizationName.toString() + "/organizationSettings");
+
+ // Call the API.
+ OrganizationSettings response = client.getOrganizationSettings(request.build());
+
+ System.out.println("Organization Settings:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_get_org_settings]
+
+ /**
+ * Update Asset Discovery OrganizationSettings for an organization
+ *
+ * @param organizationName The organization to update settings for.
+ */
+ // [START securitycenter_enable_asset_discovery]
+ static OrganizationSettings updateOrganizationSettings(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to update OrganizationSettings for.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ OrganizationSettings organizationSettings =
+ OrganizationSettings.newBuilder()
+ .setName(organizationName.toString() + "/organizationSettings")
+ .setEnableAssetDiscovery(true)
+ .build();
+ FieldMask updateMask = FieldMask.newBuilder().addPaths("enable_asset_discovery").build();
+
+ UpdateOrganizationSettingsRequest.Builder request =
+ UpdateOrganizationSettingsRequest.newBuilder()
+ .setOrganizationSettings(organizationSettings)
+ .setUpdateMask(updateMask);
+
+ // Call the API.
+ OrganizationSettings response = client.updateOrganizationSettings(request.build());
+
+ System.out.println("Organization Settings have been updated:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_enable_asset_discovery]
+
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SecurityMarkSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SecurityMarkSnippets.java
new file mode 100644
index 000000000000..611ad9e43844
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SecurityMarkSnippets.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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
+ *
+ * https://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 com.google.cloud.examples.securitycenter.snippets;
+
+import com.google.cloud.securitycenter.v1.FindingName;
+import com.google.cloud.securitycenter.v1.ListAssetsRequest;
+import com.google.cloud.securitycenter.v1.ListAssetsResponse.ListAssetsResult;
+import com.google.cloud.securitycenter.v1.ListFindingsRequest;
+import com.google.cloud.securitycenter.v1.ListFindingsResponse.ListFindingsResult;
+import com.google.cloud.securitycenter.v1.OrganizationName;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListAssetsPagedResponse;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListFindingsPagedResponse;
+import com.google.cloud.securitycenter.v1.SecurityMarks;
+import com.google.cloud.securitycenter.v1.SourceName;
+import com.google.cloud.securitycenter.v1.UpdateSecurityMarksRequest;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.protobuf.FieldMask;
+import java.io.IOException;
+
+public class SecurityMarkSnippets {
+
+ private SecurityMarkSnippets() {}
+
+ /**
+ * Add security mark to an asset.
+ *
+ * @param assetName The asset resource to add the security mark for.
+ */
+ // [START securitycenter_add_security_marks]
+ static SecurityMarks addToAsset(String assetName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // String assetName = "organizations/123123342/assets/12312321";
+ // Start setting up a request to add security marks for an asset.
+ ImmutableMap markMap = ImmutableMap.of("key_a", "value_a", "key_b", "value_b");
+
+ // Add security marks and field mask for security marks.
+ SecurityMarks securityMarks =
+ SecurityMarks.newBuilder()
+ .setName(assetName + "/securityMarks")
+ .putAllMarks(markMap)
+ .build();
+ FieldMask updateMask =
+ FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();
+
+ UpdateSecurityMarksRequest request =
+ UpdateSecurityMarksRequest.newBuilder()
+ .setSecurityMarks(securityMarks)
+ .setUpdateMask(updateMask)
+ .build();
+
+ // Call the API.
+ SecurityMarks response = client.updateSecurityMarks(request);
+
+ System.out.println("Security Marks:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_add_security_marks]
+
+ /**
+ * Clear security marks for an asset.
+ *
+ * @param assetName The asset resource to clear the security marks for.
+ */
+ // [START securitycenter_delete_security_marks]
+ static SecurityMarks clearFromAsset(String assetName) {
+ // String assetName = "organizations/123123342/assets/12312321";
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to clear security marks for an asset.
+ // Create security mark and field mask for clearing security marks.
+ SecurityMarks securityMarks =
+ SecurityMarks.newBuilder().setName(assetName + "/securityMarks").build();
+ FieldMask updateMask =
+ FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();
+
+ UpdateSecurityMarksRequest request =
+ UpdateSecurityMarksRequest.newBuilder()
+ .setSecurityMarks(securityMarks)
+ .setUpdateMask(updateMask)
+ .build();
+
+ // Call the API.
+ SecurityMarks response = client.updateSecurityMarks(request);
+
+ System.out.println("Security Marks cleared:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_delete_security_marks]
+
+ /**
+ * Deletes and updates a security mark for an asset.
+ *
+ * @param assetName The asset resource path to update and remove the security marks for.
+ */
+ // [START securitycenter_add_delete_security_marks]
+ static SecurityMarks deleteAndUpdateMarks(String assetName) {
+ // String assetName = "organizations/123123342/assets/12312321";
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to clear and update security marks for an asset.
+ // Create security mark and field mask for clearing security marks.
+ SecurityMarks securityMarks =
+ SecurityMarks.newBuilder()
+ .setName(assetName + "/securityMarks")
+ .putMarks("key_a", "new_value_for_a")
+ .build();
+ FieldMask updateMask =
+ FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();
+
+ UpdateSecurityMarksRequest request =
+ UpdateSecurityMarksRequest.newBuilder()
+ .setSecurityMarks(securityMarks)
+ .setUpdateMask(updateMask)
+ .build();
+
+ // Call the API.
+ SecurityMarks response = client.updateSecurityMarks(request);
+
+ System.out.println("Security Marks updated and cleared:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_add_delete_security_marks]
+
+ /**
+ * Add security mark to a finding.
+ *
+ * @param findingName The finding resource path to add the security mark for.
+ */
+ // [START securitycenter_add_finding_security_marks]
+ static SecurityMarks addToFinding(FindingName findingName) {
+ // FindingName findingName = FindingName.of(/*organization=*/"123234324",
+ // /*source=*/"423432321", /*findingId=*/"samplefindingid2");
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to add security marks for a finding.
+ ImmutableMap markMap = ImmutableMap.of("key_a", "value_a", "key_b", "value_b");
+
+ // Add security marks and field mask for security marks.
+ SecurityMarks securityMarks =
+ SecurityMarks.newBuilder()
+ .setName(findingName + "/securityMarks")
+ .putAllMarks(markMap)
+ .build();
+ FieldMask updateMask =
+ FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();
+
+ UpdateSecurityMarksRequest request =
+ UpdateSecurityMarksRequest.newBuilder()
+ .setSecurityMarks(securityMarks)
+ .setUpdateMask(updateMask)
+ .build();
+
+ // Call the API.
+ SecurityMarks response = client.updateSecurityMarks(request);
+
+ System.out.println("Security Marks:");
+ System.out.println(response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_add_finding_security_marks]
+
+ /**
+ * Lists all assets with a filter on security marks.
+ *
+ * @param organizationName The organization to list assets for.
+ */
+ // [START securitycenter_list_assets_with_security_marks]
+ static ImmutableList listAssetsWithQueryMarks(
+ OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to list all assets filtered by a specific security mark.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ ListAssetsRequest request =
+ ListAssetsRequest.newBuilder()
+ .setParent(organizationName.toString())
+ .setFilter("security_marks.marks.key_a = \"value_a\"")
+ .build();
+
+ // Call the API.
+ ListAssetsPagedResponse response = client.listAssets(request);
+
+ // This creates one list for all assets. If your organization has a large number of assets
+ // this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Assets with security mark - key_a=value_a:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_assets_with_security_marks]
+
+ /**
+ * List all findings with a filter on security marks.
+ *
+ * @param sourceName The source to list filtered findings for.
+ */
+ // [START securitycenter_list_findings_with_security_marks]
+ static ImmutableList listFindingsWithQueryMarks(SourceName sourceName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request for to list all findings filtered by a specific security mark.
+ // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
+ // "423432321");
+
+ String filter = "NOT security_marks.marks.key_a=\"value_a\"";
+
+ ListFindingsRequest.Builder request =
+ ListFindingsRequest.newBuilder().setParent(sourceName.toString()).setFilter(filter);
+
+ // Call the API.
+ ListFindingsPagedResponse response = client.listFindings(request.build());
+
+ // This creates one list for all findings in the filter.If your organization has a large
+ // number of
+ // findings this can cause out of memory issues. You can process them batches by returning
+ // the Iterable returned response.iterateAll() directly.
+ ImmutableList results = ImmutableList.copyOf(response.iterateAll());
+ System.out.println("Findings with security mark - key_a=value_a:");
+ System.out.println(results);
+ return results;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_list_findings_with_security_marks]
+
+}
diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SourceSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SourceSnippets.java
new file mode 100644
index 000000000000..06abf90c5c77
--- /dev/null
+++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/securitycenter/snippets/SourceSnippets.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * 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
+ *
+ * https://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 com.google.cloud.examples.securitycenter.snippets;
+
+import com.google.cloud.securitycenter.v1.CreateSourceRequest;
+import com.google.cloud.securitycenter.v1.GetSourceRequest;
+import com.google.cloud.securitycenter.v1.ListSourcesRequest;
+import com.google.cloud.securitycenter.v1.OrganizationName;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient;
+import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListSourcesPagedResponse;
+import com.google.cloud.securitycenter.v1.Source;
+import com.google.cloud.securitycenter.v1.SourceName;
+import com.google.cloud.securitycenter.v1.UpdateSourceRequest;
+import com.google.common.collect.ImmutableList;
+import com.google.iam.v1.Binding;
+import com.google.iam.v1.GetIamPolicyRequest;
+import com.google.iam.v1.Policy;
+import com.google.iam.v1.SetIamPolicyRequest;
+import com.google.protobuf.FieldMask;
+import java.io.IOException;
+
+/** Snippets for how to work with Sources in Cloud Security Command Center. */
+public class SourceSnippets {
+ private SourceSnippets() {}
+
+ /**
+ * Create a source under an organization.
+ *
+ * @param organizationName The organization for the source.
+ */
+ // [START securitycenter_create_source]
+ static Source createSource(OrganizationName organizationName) {
+ try (SecurityCenterClient client = SecurityCenterClient.create()) {
+ // Start setting up a request to create a source in an organization.
+ // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
+ Source source =
+ Source.newBuilder()
+ .setDisplayName("Customized Display Name")
+ .setDescription("A new custom source that does X")
+ .build();
+
+ CreateSourceRequest.Builder request =
+ CreateSourceRequest.newBuilder().setParent(organizationName.toString()).setSource(source);
+
+ // Call the API.
+ Source response = client.createSource(request.build());
+
+ System.out.println("Created Source: " + response);
+ return response;
+ } catch (IOException e) {
+ throw new RuntimeException("Couldn't create client.", e);
+ }
+ }
+ // [END securitycenter_create_source]
+
+ /**
+ * List sources under an organization.
+ *
+ * @param organizationName The organization for the source.
+ */
+ // [START securitycenter_list_sources]
+ static ImmutableList