Skip to content

Commit

Permalink
docs: samples and tests for auto-generated createDatabase and createI…
Browse files Browse the repository at this point in the history
…nstance APIs. (#2764)

* fix: prevent illegal negative timeout values into thread sleep() method while retrying exceptions in unit tests.

* For details on issue see - #2206

* Fixing lint issues.

* chore: adding a few samples with auto-gen clients.

* chore: adding integration tests for samples.

* chore: fixing the end-point for staging.

* chore: modified test for CreateDatabaseWithDefaultLeaderSample.

* chore: adding sample and integration test for CreateInstanceSample.

* chore: adding license headers.

* chore: fix lint errors.

* chore: rename file and add sample tags.

* chore: address comments.

* Update samples/snippets/src/main/java/com/example/spanner/v2/CreateDatabaseWithDefaultLeaderSample.java

Co-authored-by: Knut Olav Løite <koloite@gmail.com>

* chore: rename file path.

* chore: remove admin settings.

* chore: address comments.

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

---------

Co-authored-by: Knut Olav Løite <koloite@gmail.com>
Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 3, 2024
1 parent 21f5eba commit 74a586f
Show file tree
Hide file tree
Showing 11 changed files with 463 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -330,6 +330,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
| Update Jsonb Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) |
| Update Numeric Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) |
| Update Using Dml Returning Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateUsingDmlReturningSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateUsingDmlReturningSample.java) |
| Create Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateDatabaseWithDefaultLeaderSample.java) |
| Create Instance Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/admin/generated/CreateInstanceExample.java) |



Expand Down
6 changes: 3 additions & 3 deletions samples/install-without-bom/pom.xml
Expand Up @@ -142,9 +142,9 @@
<version>3.1.2</version>
<configuration>
<systemPropertyVariables>
<spanner.test.instance>spanner-testing-east1</spanner.test.instance>
<spanner.test.instance.mr>spanner-mr-testing</spanner.test.instance.mr>
<spanner.test.instance.config>nam6</spanner.test.instance.config>
<spanner.test.instance>java-client-integration-test</spanner.test.instance>
<spanner.test.instance.mr>java-client-mr-integration-test</spanner.test.instance.mr>
<spanner.test.instance.config>nam15</spanner.test.instance.config>
<spanner.test.key.location>us-east1</spanner.test.key.location>
<spanner.test.key.ring>cmek-test-key-ring</spanner.test.key.ring>
<spanner.test.key.name>cmek-test-key</spanner.test.key.name>
Expand Down
7 changes: 4 additions & 3 deletions samples/snapshot/pom.xml
Expand Up @@ -141,13 +141,14 @@
<version>3.1.2</version>
<configuration>
<systemPropertyVariables>
<spanner.test.instance>spanner-testing-east1</spanner.test.instance>
<spanner.test.instance.mr>spanner-mr-testing</spanner.test.instance.mr>
<spanner.test.instance.config>nam6</spanner.test.instance.config>
<spanner.test.instance>java-client-integration-test</spanner.test.instance>
<spanner.test.instance.mr>java-client-mr-integration-test</spanner.test.instance.mr>
<spanner.test.instance.config>nam15</spanner.test.instance.config>
<spanner.test.key.location>us-east1</spanner.test.key.location>
<spanner.test.key.ring>cmek-test-key-ring</spanner.test.key.ring>
<spanner.test.key.name>cmek-test-key</spanner.test.key.name>
<spanner.sample.database>mysample</spanner.sample.database>
<spanner.sample.instance>mysample-instance</spanner.sample.instance>
<spanner.quickstart.database>quick-db</spanner.quickstart.database>
</systemPropertyVariables>
</configuration>
Expand Down
6 changes: 3 additions & 3 deletions samples/snippets/pom.xml
Expand Up @@ -178,9 +178,9 @@
<version>3.1.2</version>
<configuration>
<systemPropertyVariables>
<spanner.test.instance>spanner-testing-east1</spanner.test.instance>
<spanner.test.instance.mr>spanner-mr-testing</spanner.test.instance.mr>
<spanner.test.instance.config>nam6</spanner.test.instance.config>
<spanner.test.instance>java-client-integration-test</spanner.test.instance>
<spanner.test.instance.mr>java-client-mr-integration-test</spanner.test.instance.mr>
<spanner.test.instance.config>nam15</spanner.test.instance.config>
<spanner.test.key.location>us-east1</spanner.test.key.location>
<spanner.test.key.ring>cmek-test-key-ring</spanner.test.key.ring>
<spanner.test.key.name>cmek-test-key</spanner.test.key.name>
Expand Down
@@ -0,0 +1,78 @@
/*
* Copyright 2023 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.example.spanner.admin.generated;

//[START spanner_create_database_with_default_leader]

import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
import com.google.common.collect.ImmutableList;
import com.google.spanner.admin.database.v1.CreateDatabaseRequest;
import com.google.spanner.admin.database.v1.Database;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

public class CreateDatabaseWithDefaultLeaderSample {

static void createDatabaseWithDefaultLeader() throws IOException {
// TODO(developer): Replace these variables before running the sample.
final String instanceName = "projects/my-project/instances/my-instance-id";
final String databaseId = "my-database-name";
final String defaultLeader = "my-default-leader";
createDatabaseWithDefaultLeader(instanceName, databaseId, defaultLeader);
}

static void createDatabaseWithDefaultLeader(String instanceName, String databaseId,
String defaultLeader) throws IOException {
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();

try {
Database createdDatabase =
databaseAdminClient.createDatabaseAsync(
CreateDatabaseRequest.newBuilder()
.setParent(instanceName)
.setCreateStatement("CREATE DATABASE `" + databaseId + "`")
.addAllExtraStatements(
ImmutableList.of("CREATE TABLE Singers ("
+ " SingerId INT64 NOT NULL,"
+ " FirstName STRING(1024),"
+ " LastName STRING(1024),"
+ " SingerInfo BYTES(MAX)"
+ ") PRIMARY KEY (SingerId)",
"CREATE TABLE Albums ("
+ " SingerId INT64 NOT NULL,"
+ " AlbumId INT64 NOT NULL,"
+ " AlbumTitle STRING(MAX)"
+ ") PRIMARY KEY (SingerId, AlbumId),"
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE",
"ALTER DATABASE " + "`" + databaseId + "`"
+ " SET OPTIONS ( default_leader = '" + defaultLeader + "' )"))
.build()).get();
System.out.println("Created database [" + createdDatabase.getName() + "]");
System.out.println("\tDefault leader: " + createdDatabase.getDefaultLeader());
} catch (ExecutionException e) {
// If the operation failed during execution, expose the cause.
throw (SpannerException) e.getCause();
} catch (InterruptedException e) {
// Throw when a thread is waiting, sleeping, or otherwise occupied,
// and the thread is interrupted, either before or during the activity.
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
}
//[END spanner_create_database_with_default_leader]
@@ -0,0 +1,70 @@
/*
* Copyright 2023 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.example.spanner.admin.generated;

//[START spanner_create_instance]
import com.google.cloud.spanner.admin.instance.v1.InstanceAdminClient;
import com.google.spanner.admin.instance.v1.CreateInstanceRequest;
import com.google.spanner.admin.instance.v1.Instance;
import com.google.spanner.admin.instance.v1.InstanceConfigName;
import com.google.spanner.admin.instance.v1.ProjectName;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

class CreateInstanceExample {

static void createInstance() throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "my-project";
String instanceId = "my-instance";
createInstance(projectId, instanceId);
}

static void createInstance(String projectId, String instanceId) throws IOException {
InstanceAdminClient instanceAdminClient = InstanceAdminClient.create();

// Set Instance configuration.
int nodeCount = 2;
String displayName = "Descriptive name";

// Create an Instance object that will be used to create the instance.
Instance instance =
Instance.newBuilder()
.setDisplayName(displayName)
.setNodeCount(nodeCount)
.setConfig(
InstanceConfigName.of(projectId, "regional-us-central1").toString())
.build();
try {
// Wait for the createInstance operation to finish.
Instance createdInstance = instanceAdminClient.createInstanceAsync(
CreateInstanceRequest.newBuilder()
.setParent(ProjectName.of(projectId).toString())
.setInstanceId(instanceId)
.setInstance(instance)
.build()).get();
System.out.printf("Instance %s was successfully created%n", createdInstance.getName());
} catch (ExecutionException e) {
System.out.printf(
"Error: Creating instance %s failed with error message %s%n",
instance.getName(), e.getMessage());
} catch (InterruptedException e) {
System.out.println("Error: Waiting for createInstance operation to finish was interrupted");
}
}
}
//[END spanner_create_instance]
Expand Up @@ -26,24 +26,38 @@
*/
public class SampleIdGenerator {

private static final int INSTANCE_NAME_MAX_LENGTH = 30;
private static final int DATABASE_NAME_MAX_LENGTH = 30;
private static final int BACKUP_NAME_MAX_LENGTH = 30;
private static final int INSTANCE_CONFIG_ID_MAX_LENGTH = 30;
private final List<String> instanceIds;
private final List<String> databaseIds;
private final List<String> backupIds;
private final List<String> instanceConfigIds;
private final String baseDatabaseId;
private final String baseBackupId;
private final String baseInstanceConfigId;
private final String baseInstanceId;

public SampleIdGenerator(
String baseDatabaseId, String baseBackupId, String baseInstanceConfigId) {
public SampleIdGenerator(String baseDatabaseId, String baseBackupId,
String baseInstanceConfigId, String baseInstanceId) {
this.baseDatabaseId = baseDatabaseId;
this.baseBackupId = baseBackupId;
this.baseInstanceConfigId = baseInstanceConfigId;
this.baseInstanceId = baseInstanceId;
this.databaseIds = new ArrayList<>();
this.backupIds = new ArrayList<>();
this.instanceConfigIds = new ArrayList<>();
this.instanceIds = new ArrayList<>();
}

public String generateInstanceId() {
final String instanceId =
(baseInstanceId + "-" + UUID.randomUUID().toString().replaceAll("-", ""))
.substring(0, INSTANCE_NAME_MAX_LENGTH);

instanceIds.add(instanceId);
return instanceId;
}

public String generateDatabaseId() {
Expand Down Expand Up @@ -81,6 +95,10 @@ public List<String> getBackupIds() {
return backupIds;
}

public List<String> getInstanceIds() {
return instanceIds;
}

public List<String> getInstanceConfigIds() {
return instanceConfigIds;
}
Expand Down
Expand Up @@ -25,7 +25,8 @@

/** Base class for sample integration tests. */
public class SampleTestBase {

private static final String BASE_INSTANCE_ID =
System.getProperty("spanner.sample.instance", "mysample-instance");
private static final String BASE_DATABASE_ID =
System.getProperty("spanner.sample.database", "sampledb");
private static final String BASE_BACKUP_ID = "samplebk";
Expand Down Expand Up @@ -56,11 +57,27 @@ public static void beforeClass() {
spanner = options.getService();
databaseAdminClient = spanner.getDatabaseAdminClient();
instanceAdminClient = spanner.getInstanceAdminClient();
idGenerator = new SampleIdGenerator(BASE_DATABASE_ID, BASE_BACKUP_ID, BASE_INSTANCE_CONFIG_ID);
idGenerator = new SampleIdGenerator(
BASE_DATABASE_ID, BASE_BACKUP_ID, BASE_INSTANCE_CONFIG_ID, BASE_INSTANCE_ID);
}

@AfterClass
public static void afterClass() {
for (String instanceId : idGenerator.getInstanceIds()) {
System.out.println("Trying to drop " + instanceId);
try {
// If the database is not found, it is ignored (no exception is thrown)
instanceAdminClient.deleteInstance(instanceId);
} catch (Exception e) {
System.out.println(
"Failed to drop instance "
+ instanceId
+ " due to "
+ e.getMessage()
+ ", skipping...");
}
}

for (String databaseId : idGenerator.getDatabaseIds()) {
System.out.println("Trying to drop " + databaseId);
try {
Expand Down
@@ -0,0 +1,61 @@
/*
* Copyright 2023 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.example.spanner.admin.generated;

import static org.junit.Assert.assertTrue;

import com.example.spanner.SampleRunner;
import com.google.spanner.admin.instance.v1.InstanceConfig;
import com.google.spanner.admin.instance.v1.InstanceName;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class CreateDatabaseWithDefaultLeaderSampleIT extends SampleTestBaseV2 {

@Test
public void testCreateDatabaseWithDefaultLeader() throws Exception {
final String databaseId = idGenerator.generateDatabaseId();

// Finds possible default leader

final String instanceConfigId = instanceAdminClient.getInstance(
InstanceName.of(projectId, multiRegionalInstanceId)).getConfig();
final InstanceConfig config = instanceAdminClient.getInstanceConfig(instanceConfigId);
assertTrue(
"Expected instance config " + instanceConfigId + " to have at least one leader option",
config.getLeaderOptionsCount() > 0
);
final String defaultLeader = config.getLeaderOptions(0);

// Runs sample
final String out = SampleRunner.runSample(() ->
CreateDatabaseWithDefaultLeaderSample.createDatabaseWithDefaultLeader(
getInstanceName(projectId, multiRegionalInstanceId),
databaseId,
defaultLeader
)
);

assertTrue(
"Expected created database to have default leader " + defaultLeader + "."
+ " Output received was " + out,
out.contains("Default leader: " + defaultLeader)
);
}
}

0 comments on commit 74a586f

Please sign in to comment.