public final class BigtableInstanceAdminClient extends Object implements AutoCloseable
See the individual methods for example code.
 try(BigtableInstanceAdminClient client =  BigtableInstanceAdminClient.create("my-project")) {
   CreateInstanceRequest request = CreateInstanceRequest.of("my-instance")
     .addCluster("my-cluster", "us-east1-c", 3, StorageType.SSD);
   Instance instance = client.createInstance(request);
 }
 
 Note: close() needs to be called on the client object to clean up resources such as threads. In the example above, try-with-resources is used, which automatically calls close().
This class can be customized by passing in a custom instance of BigtableInstanceAdminSettings to create(). For example:
To customize credentials:
 BigtableInstanceAdminSettings settings = BigtableInstanceAdminSettings.newBuilder()
   .setProjectId("my-project")
   .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
   .build();
 BigtableInstanceAdminClient client = BigtableInstanceAdminClient.create(settings);
 
 To customize the endpoint:
 
 BigtableInstanceAdminSettings settings = BigtableInstanceAdminSettings.newBuilder()
   .setProjectId("my-project")
   .setEndpoint(myEndpoint)
   .build();
 BigtableInstanceAdminClient client = BigtableInstanceAdminClient.create(settings);
 | Modifier and Type | Method and Description | 
|---|---|
void | 
close()
Closes the client and frees all resources associated with it (like thread pools). 
 | 
static BigtableInstanceAdminClient | 
create(BigtableInstanceAdminSettings settings)
Constructs an instance of BigtableInstanceAdminClient with the given settings. 
 | 
static BigtableInstanceAdminClient | 
create(ProjectName projectName)
Deprecated. 
 
Please use  
create(String). | 
static BigtableInstanceAdminClient | 
create(ProjectName projectName,
      com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub stub)
Deprecated. 
 
Please use  
create(String, BigtableInstanceAdminStub). | 
static BigtableInstanceAdminClient | 
create(String projectId)
Constructs an instance of BigtableInstanceAdminClient with the given project ID. 
 | 
static BigtableInstanceAdminClient | 
create(String projectId,
      com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub stub)
Constructs an instance of BigtableInstanceAdminClient with the given project ID and stub. 
 | 
AppProfile | 
createAppProfile(CreateAppProfileRequest request)
Creates a new app profile. 
 | 
com.google.api.core.ApiFuture<AppProfile> | 
createAppProfileAsync(CreateAppProfileRequest request)
Asynchronously creates a new app profile. 
 | 
Cluster | 
createCluster(CreateClusterRequest request)
Creates a new cluster in the specified instance. 
 | 
com.google.api.core.ApiFuture<Cluster> | 
createClusterAsync(CreateClusterRequest request)
Asynchronously creates a new cluster in the specified instance. 
 | 
Instance | 
createInstance(CreateInstanceRequest request)
Creates a new instance and returns its representation. 
 | 
com.google.api.core.ApiFuture<Instance> | 
createInstanceAsync(CreateInstanceRequest request)
Asynchronously creates a new instance and returns its representation wrapped in a future. 
 | 
void | 
deleteAppProfile(String instanceId,
                String appProfileId)
Deletes the specified app profile. 
 | 
com.google.api.core.ApiFuture<Void> | 
deleteAppProfileAsync(String instanceId,
                     String appProfileId)
Asynchronously deletes the specified app profile. 
 | 
void | 
deleteCluster(String instanceId,
             String clusterId)
Deletes the specified cluster. 
 | 
com.google.api.core.ApiFuture<Void> | 
deleteClusterAsync(String instanceId,
                  String clusterId)
Asynchronously deletes the specified cluster. 
 | 
void | 
deleteInstance(String instanceId)
Deletes the specified instance. 
 | 
com.google.api.core.ApiFuture<Void> | 
deleteInstanceAsync(String instanceId)
Asynchronously deletes the specified instance. 
 | 
boolean | 
exists(String instanceId)
Checks if the instance specified by the instance ID exists. 
 | 
com.google.api.core.ApiFuture<Boolean> | 
existsAsync(String instanceId)
Asynchronously checks if the instance specified by the instance ID exists. 
 | 
AppProfile | 
getAppProfile(String instanceId,
             String appProfileId)
Gets the app profile by ID. 
 | 
com.google.api.core.ApiFuture<AppProfile> | 
getAppProfileAsync(String instanceId,
                  String appProfileId)
Asynchronously gets the app profile by ID. 
 | 
Cluster | 
getCluster(String instanceId,
          String clusterId)
Gets the cluster representation by ID. 
 | 
com.google.api.core.ApiFuture<Cluster> | 
getClusterAsync(String instanceId,
               String clusterId)
Asynchronously gets the cluster representation by ID. 
 | 
Policy | 
getIamPolicy(String instanceId)
Gets the IAM access control policy for the specified instance. 
 | 
com.google.api.core.ApiFuture<Policy> | 
getIamPolicyAsync(String instanceId)
Asynchronously gets the IAM access control policy for the specified instance. 
 | 
Instance | 
getInstance(String id)
Get the instance representation by ID. 
 | 
com.google.api.core.ApiFuture<Instance> | 
getInstanceAsync(String instanceId)
Asynchronously gets the instance representation by ID wrapped in a future. 
 | 
String | 
getProjectId()
Gets the project ID this client is associated with. 
 | 
ProjectName | 
getProjectName()
Deprecated. 
 
Please use  
getProjectId(). | 
List<AppProfile> | 
listAppProfiles(String instanceId)
Lists all app profiles of the specified instance. 
 | 
com.google.api.core.ApiFuture<List<AppProfile>> | 
listAppProfilesAsync(String instanceId)
Asynchronously lists all app profiles of the specified instance. 
 | 
List<Cluster> | 
listClusters(String instanceId)
Lists all clusters in the specified instance. 
 | 
com.google.api.core.ApiFuture<List<Cluster>> | 
listClustersAsync(String instanceId)
Asynchronously lists all clusters in the specified instance. 
 | 
List<Instance> | 
listInstances()
Lists all of the instances in the current project. 
 | 
com.google.api.core.ApiFuture<List<Instance>> | 
listInstancesAsync()
Asynchronously lists all of the instances in the current project. 
 | 
Cluster | 
resizeCluster(String instanceId,
             String clusterId,
             int numServeNodes)
Modifies the cluster's node count. 
 | 
com.google.api.core.ApiFuture<Cluster> | 
resizeClusterAsync(String instanceId,
                  String clusterId,
                  int numServeNodes)
Asynchronously modifies the cluster's node count. 
 | 
Policy | 
setIamPolicy(String instanceId,
            Policy policy)
Replaces the IAM policy associated with the specified instance. 
 | 
com.google.api.core.ApiFuture<Policy> | 
setIamPolicyAsync(String instanceId,
                 Policy policy)
Asynchronously replaces the IAM policy associated with the specified instance. 
 | 
List<String> | 
testIamPermission(com.google.api.resourcenames.ResourceName resourceName,
                 String... permissions)
Deprecated. 
 
Please use  
testIamPermission(String, String...). | 
List<String> | 
testIamPermission(String instanceId,
                 String... permissions)
Tests whether the caller has the given permissions for the specified instance. 
 | 
com.google.api.core.ApiFuture<List<String>> | 
testIamPermissionAsync(com.google.api.resourcenames.ResourceName resourceName,
                      String... permissions)
Deprecated. 
 
Please use  
testIamPermissionAsync(String, String...) | 
com.google.api.core.ApiFuture<List<String>> | 
testIamPermissionAsync(String instanceId,
                      String... permissions)
Asynchronously tests whether the caller has the given permissions for the specified instance. 
 | 
AppProfile | 
updateAppProfile(UpdateAppProfileRequest request)
Updates an existing app profile. 
 | 
com.google.api.core.ApiFuture<AppProfile> | 
updateAppProfileAsync(UpdateAppProfileRequest request)
Asynchronously updates an existing app profile. 
 | 
Instance | 
updateInstance(UpdateInstanceRequest request)
Updates a new instance and returns its representation. 
 | 
com.google.api.core.ApiFuture<Instance> | 
updateInstanceAsync(UpdateInstanceRequest request)
Asynchronously updates a new instance and returns its representation wrapped in a future. 
 | 
public static BigtableInstanceAdminClient create(@Nonnull String projectId) throws IOException
IOException@Deprecated public static BigtableInstanceAdminClient create(@Nonnull ProjectName projectName) throws IOException
create(String).IOExceptionpublic static BigtableInstanceAdminClient create(@Nonnull BigtableInstanceAdminSettings settings) throws IOException
IOExceptionpublic static BigtableInstanceAdminClient create(@Nonnull String projectId, @Nonnull com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub stub)
@Deprecated public static BigtableInstanceAdminClient create(@Nonnull ProjectName projectName, @Nonnull com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub stub)
create(String, BigtableInstanceAdminStub).public String getProjectId()
@Deprecated public ProjectName getProjectName()
getProjectId().public void close()
close in interface AutoCloseablepublic Instance createInstance(CreateInstanceRequest request)
Sample code:
 Instance instance = client.createInstance(
   CreateInstanceRequest.of("my-instance")
     .addCluster("my-cluster", "us-east1-c", 3, StorageType.SSD)
 );
 for details.public com.google.api.core.ApiFuture<Instance> createInstanceAsync(CreateInstanceRequest request)
Sample code:
 ApiFuture<Instance> instanceFuture = client.createInstanceAsync(
   CreateInstanceRequest.of("my-instance")
     .addCluster("my-cluster", "us-east1-c", 3, StorageType.SSD)
 );
 Instance instance = instanceFuture.get();
 for details.public Instance updateInstance(UpdateInstanceRequest request)
Sample code:
 Instance instance = client.updateInstance(
   UpdateInstanceRequest.of("my-instance")
     .setProductionType()
 );
 for details.public com.google.api.core.ApiFuture<Instance> updateInstanceAsync(UpdateInstanceRequest request)
Sample code:
 ApiFuture<Instance> instanceFuture = client.updateInstanceAsync(
   UpdateInstanceRequest.of("my-instance")
     .setProductionType()
 );
 Instance instance = instanceFuture.get();
 for details.public Instance getInstance(String id)
Sample code:
 Instance instance = client.getInstance("my-instance");
 public com.google.api.core.ApiFuture<Instance> getInstanceAsync(String instanceId)
Sample code:
 ApiFuture<Instance> instanceFuture = client.getInstanceAsync("my-instance");
 Instance instance = instanceFuture.get();
 public List<Instance> listInstances()
This method will throw a PartialListInstancesException when any zone is unavailable.
 If a partial list is OK, the exception can be caught and inspected.
 
Sample code:
 try {
   List<Instance> instances = client.listInstances();
 } catch (PartialListInstancesException e) {
   System.out.println("The following zones are unavailable: " + e.getUnavailableZones());
   System.out.println("But the following instances are reachable: " + e.getInstances());
 }
 public com.google.api.core.ApiFuture<List<Instance>> listInstancesAsync()
This method will throw a PartialListInstancesException when any zone is unavailable.
 If a partial list is OK, the exception can be caught and inspected.
 
Sample code:
 ApiFuture<Instance> instancesFuture = client.listInstancesAsync();
 ApiFutures.addCallback(instancesFuture, new ApiFutureCallback<List<Instance>>() {
   public void onFailure(Throwable t) {
     if (t instanceof PartialListInstancesException) {
       PartialListInstancesException partialError = (PartialListInstancesException)t;
       System.out.println("The following zones are unavailable: " + partialError.getUnavailableZones());
       System.out.println("But the following instances are reachable: " + partialError.getInstances());
     } else {
       t.printStackTrace();
     }
   }
   public void onSuccess(List<Instance> result) {
     System.out.println("Found a complete set of instances: " + result);
   }
 }, MoreExecutors.directExecutor());
 public void deleteInstance(String instanceId)
Sample code:
 client.deleteInstance("my-instance");
 public com.google.api.core.ApiFuture<Void> deleteInstanceAsync(String instanceId)
Sample code:
 ApiFuture<Void> deleteFuture = client.deleteInstanceAsync("my-instance");
 deleteFuture.get();
 public boolean exists(String instanceId)
Sample code:
 if(client.exists("my-instance")) {
   System.out.println("Instance exists");
 }
 public com.google.api.core.ApiFuture<Boolean> existsAsync(String instanceId)
Sample code:
 ApiFuture<Boolean> found = client.existsAsync("my-instance");
 ApiFutures.addCallback(
  found,
  new ApiFutureCallback<Boolean>() {
    public void onSuccess(Boolean found) {
      if (found) {
        System.out.println("Instance exists");
      } else {
        System.out.println("Instance not found");
      }
    }
    public void onFailure(Throwable t) {
      t.printStackTrace();
    }
  },
  MoreExecutors.directExecutor()
 );
 public Cluster createCluster(CreateClusterRequest request)
Sample code:
 Cluster cluster = client.createCluster(
   CreateClusterRequest.of("my-instance", "my-new-cluster")
     .setZone("us-east1-c")
     .setServeNodes(3)
     .setStorageType(StorageType.SSD)
 );
 public com.google.api.core.ApiFuture<Cluster> createClusterAsync(CreateClusterRequest request)
Sample code:
 ApiFuture<Cluster> clusterFuture = client.createClusterAsync(
   CreateClusterRequest.of("my-instance", "my-new-cluster")
     .setZone("us-east1-c")
     .setServeNodes(3)
     .setStorageType(StorageType.SSD)
 );
 Cluster cluster = clusterFuture.get();
 public Cluster getCluster(String instanceId, String clusterId)
Sample code:
 Cluster cluster = client.getCluster("my-instance", "my-cluster");
 public com.google.api.core.ApiFuture<Cluster> getClusterAsync(String instanceId, String clusterId)
Sample code:
 ApiFuture<Cluster> clusterFuture = client.getClusterAsync("my-instance", "my-cluster");
 Cluster cluster = clusterFuture.get();
 public List<Cluster> listClusters(String instanceId)
This method will throw a PartialListClustersException when any zone is unavailable.
 If a partial list is OK, the exception can be caught and inspected.
 
Sample code:
 try {
   List<Cluster> clusters = client.listClusters("my-instance");
 } catch (PartialListClustersException e) {
   System.out.println("The following zones are unavailable: " + e.getUnavailableZones());
   System.out.println("But the following clusters are reachable: " + e.getClusters())
 }
 public com.google.api.core.ApiFuture<List<Cluster>> listClustersAsync(String instanceId)
This method will throw a PartialListClustersException when any zone is unavailable.
 If a partial list is OK, the exception can be caught and inspected.
 
Sample code:
 ApiFuture<Cluster> clustersFuture = client.listClustersAsync("my-instance");
 ApiFutures.addCallback(clustersFuture, new ApiFutureCallback<List<Cluster>>() {
   public void onFailure(Throwable t) {
     if (t instanceof PartialListClustersException) {
       PartialListClustersException partialError = (PartialListClustersException)t;
       System.out.println("The following zones are unavailable: " + partialError.getUnavailableZones());
       System.out.println("But the following clusters are reachable: " + partialError.getClusters());
     } else {
       t.printStackTrace();
     }
   }
   public void onSuccess(List<Cluster> result) {
     System.out.println("Found a complete set of instances: " + result);
   }
 }, MoreExecutors.directExecutor());
 public Cluster resizeCluster(String instanceId, String clusterId, int numServeNodes)
Sample code:
 Cluster cluster = client.resizeCluster("my-instance", "my-cluster", 30);
 public com.google.api.core.ApiFuture<Cluster> resizeClusterAsync(String instanceId, String clusterId, int numServeNodes)
 ApiFuture<Cluster> clusterFuture = client.resizeCluster("my-instance", "my-cluster", 30);
 Cluster cluster = clusterFuture.get();
 public void deleteCluster(String instanceId, String clusterId)
deleteInstance(String).
 Sample code:
 client.deleteCluster("my-instance", "my-cluster");
 public com.google.api.core.ApiFuture<Void> deleteClusterAsync(String instanceId, String clusterId)
deleteInstanceAsync(String).
 Sample code:
 ApiFuture<Void> future = client.deleteClusterAsync("my-instance", "my-cluster");
 future.get();
 public AppProfile createAppProfile(CreateAppProfileRequest request)
Sample code:
 AppProfile appProfile = client.createAppProfile(
   CreateAppProfileRequest.of("my-instance", "my-new-app-profile")
     .setRoutingPolicy(SingleClusterRoutingPolicy.of("my-cluster"))
 );
 CreateAppProfileRequestpublic com.google.api.core.ApiFuture<AppProfile> createAppProfileAsync(CreateAppProfileRequest request)
Sample code:
 ApiFuture<AppProfile> appProfileFuture = client.createAppProfileAsync(
   CreateAppProfileRequest.of("my-instance", "my-new-app-profile")
     .setRoutingPolicy(SingleClusterRoutingPolicy.of("my-cluster"))
 );
 AppProfile appProfile = appProfileFuture.get();
 CreateAppProfileRequestpublic AppProfile getAppProfile(String instanceId, String appProfileId)
Sample code:
 AppProfile appProfile = client.getAppProfile("my-instance", "my-app-profile");
 AppProfilepublic com.google.api.core.ApiFuture<AppProfile> getAppProfileAsync(String instanceId, String appProfileId)
Sample code:
 ApiFuture<AppProfile> appProfileFuture = client.getAppProfileAsync("my-instance", "my-app-profile");
 AppProfile appProfile = appProfileFuture.get();
 AppProfilepublic List<AppProfile> listAppProfiles(String instanceId)
Sample code:
 List<AppProfile> appProfiles = client.listAppProfiles("my-instance");
 AppProfilepublic com.google.api.core.ApiFuture<List<AppProfile>> listAppProfilesAsync(String instanceId)
Sample code:
 ApiFuture<List<AppProfile>> appProfilesFuture = client.listAppProfilesAsync("my-instance");
 List<AppProfile> appProfiles = appProfileFuture.get();
 AppProfilepublic AppProfile updateAppProfile(UpdateAppProfileRequest request)
Sample code:
 AppProfile existingAppProfile = client.getAppProfile("my-instance", "my-app-profile");
 AppProfile updatedAppProfile = client.updateAppProfile(
   UpdateAppProfileRequest.of(existingAppProfile)
     .setRoutingPolicy(SingleClusterRoutingPolicy.of("my-cluster"))
 );
 UpdateAppProfileRequestpublic com.google.api.core.ApiFuture<AppProfile> updateAppProfileAsync(UpdateAppProfileRequest request)
Sample code:
 ApiFuture<AppProfile> existingAppProfileFuture = client.getAppProfileAsync("my-instance", "my-app-profile");
 ApiFuture<AppProfile> updatedAppProfileFuture = ApiFutures.transformAsync(
   existingAppProfileFuture,
   new ApiAsyncFunction<AppProfile, AppProfile>() {
     public ApiFuture<AppProfile> apply(AppProfile existingAppProfile) {
       return client.updateAppProfileAsync(
         UpdateAppProfileRequest.of(existingAppProfile)
           .setRoutingPolicy(SingleClusterRoutingPolicy.of("my-other-cluster"))
       );
     }
   },
   MoreExecutors.directExecutor()
 );
 ApiFuture<AppProfile> appProfile = updatedAppProfileFuture.get();
 UpdateAppProfileRequestpublic void deleteAppProfile(String instanceId, String appProfileId)
Sample code:
 client.deleteAppProfile("my-instance", "my-app-profile");
 public com.google.api.core.ApiFuture<Void> deleteAppProfileAsync(String instanceId, String appProfileId)
Sample code:
 ApiFuture<Void> deleteFuture = client.deleteAppProfileAsync("my-instance", "my-app-profile");
 deleteFuture.get();
 public Policy getIamPolicy(String instanceId)
Sample code:
 Policy policy = client.getIamPolicy("my-instance");
 for(Map.Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
   System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
 }
 public com.google.api.core.ApiFuture<Policy> getIamPolicyAsync(String instanceId)
Sample code:
 ApiFuture<Policy> policyFuture = client.getIamPolicyAsync("my-instance");
 ApiFutures.addCallback(policyFuture,
   new ApiFutureCallback<Policy>() {
     public void onSuccess(Policy policy) {
       for (Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
         System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
       }
     }
     public void onFailure(Throwable t) {
       t.printStackTrace();
     }
   },
   MoreExecutors.directExecutor());
 public Policy setIamPolicy(String instanceId, Policy policy)
Sample code:
 Policy newPolicy = client.setIamPolicy("my-instance",
   Policy.newBuilder()
     .addIdentity(Role.of("bigtable.user"), Identity.user("someone@example.com"))
     .addIdentity(Role.of("bigtable.admin"), Identity.group("admins@example.com"))
     .build());
 public com.google.api.core.ApiFuture<Policy> setIamPolicyAsync(String instanceId, Policy policy)
Sample code:
 ApiFuture<Policy> newPolicyFuture = client.setIamPolicyAsync("my-instance",
   Policy.newBuilder()
     .addIdentity(Role.of("bigtable.user"), Identity.user("someone@example.com"))
     .addIdentity(Role.of("bigtable.admin"), Identity.group("admins@example.com"))
     .build());
 ApiFutures.addCallback(policyFuture,
   new ApiFutureCallback<Policy>() {
     public void onSuccess(Policy policy) {
       for (Entry<Role, Set<Identity>> entry : policy.getBindings().entrySet()) {
         System.out.printf("Role: %s Identities: %s\n", entry.getKey(), entry.getValue());
       }
     }
     public void onFailure(Throwable t) {
       t.printStackTrace();
     }
   },
   MoreExecutors.directExecutor());
 public List<String> testIamPermission(String instanceId, String... permissions)
Sample code:
 List<String> grantedPermissions = client.testIamPermission("my-instance",
   "bigtable.tables.readRows", "bigtable.tables.mutateRows");
 
 System.out.println("Has read access: " +
 grantedPermissions.contains("bigtable.tables.readRows")); System.out.println("Has write access:
 " + grantedPermissions.contains("bigtable.tables.mutateRows"));public com.google.api.core.ApiFuture<List<String>> testIamPermissionAsync(String instanceId, String... permissions)
Sample code:
 ApiFuture<List<String>> grantedPermissionsFuture = client.testIamPermissionAsync("my-instance",
   "bigtable.tables.readRows", "bigtable.tables.mutateRows");
 ApiFutures.addCallback(grantedPermissionsFuture,
   new ApiFutureCallback<List<String>>() {
     public void onSuccess(List<String> grantedPermissions) {
       System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
       System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
     }
     public void onFailure(Throwable t) {
       t.printStackTrace();
     }
   },
   MoreExecutors.directExecutor());
 @Deprecated public List<String> testIamPermission(com.google.api.resourcenames.ResourceName resourceName, String... permissions)
testIamPermission(String, String...).Returns a subset of the specified permissions that the caller has.
Sample code:
 List<String> grantedPermissions = client.testIamPermission(
   TableName.of("my-project", "my-instance", "my-table"),
   "bigtable.tables.readRows", "bigtable.tables.mutateRows");
 System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
 System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
 public com.google.api.core.ApiFuture<List<String>> testIamPermissionAsync(com.google.api.resourcenames.ResourceName resourceName, String... permissions)
testIamPermissionAsync(String, String...)Sample code:
 ApiFuture<List<String>> grantedPermissionsFuture = client.testIamPermissionAsync(
   TableName.of("my-project", "my-instance", "my-table"),
   "bigtable.tables.readRows", "bigtable.tables.mutateRows");
 ApiFutures.addCallback(grantedPermissionsFuture,
   new ApiFutureCallback<List<String>>() {
     public void onSuccess(List<String> grantedPermissions) {
       System.out.println("Has read access: " + grantedPermissions.contains("bigtable.tables.readRows"));
       System.out.println("Has write access: " + grantedPermissions.contains("bigtable.tables.mutateRows"));
     }
     public void onFailure(Throwable t) {
       t.printStackTrace();
     }
   },
   MoreExecutors.directExecutor());
 Copyright © 2019 Google LLC. All rights reserved.