com.google.cloud.spanner.SpannerException Java Examples

The following examples show how to use com.google.cloud.spanner.SpannerException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LocalSpannerIO.java    From DataflowTemplates with Apache License 2.0 6 votes vote down vote up
private void spannerWriteWithRetryIfSchemaChange(Iterable<Mutation> batch)
    throws SpannerException {
  for (int retry = 1; ; retry++) {
    try {
      spannerAccessor.getDatabaseClient().writeAtLeastOnce(batch);
      return;
    } catch (AbortedException e) {
      if (retry >= ABORTED_RETRY_ATTEMPTS) {
        throw e;
      }
      if (e.isRetryable() || e.getMessage().contains(errString)) {
        continue;
      }
      throw e;
    }
  }
}
 
Example #2
Source File: HelloSpanner.java    From java-docs-samples with Apache License 2.0 6 votes vote down vote up
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
  var writer = new PrintWriter(response.getWriter());
  try {
    DatabaseClient client = getClient();
    try (ResultSet rs =
        client
            .singleUse()
            .executeQuery(Statement.of("SELECT SingerId, AlbumId, AlbumTitle FROM Albums"))) {
      writer.printf("Albums:%n");
      while (rs.next()) {
        writer.printf(
            "%d %d %s%n",
            rs.getLong("SingerId"), rs.getLong("AlbumId"), rs.getString("AlbumTitle"));
      }
    } catch (SpannerException e) {
      writer.printf("Error querying database: %s%n", e.getMessage());
      response.setStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR, e.getMessage());
    }
  } catch (Throwable t) {
    logger.log(Level.SEVERE, "Spanner example failed", t);
    writer.printf("Error setting up Spanner: %s%n", t.getMessage());
    response.setStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR, t.getMessage());
  }
}
 
Example #3
Source File: SpannerIO.java    From beam with Apache License 2.0 6 votes vote down vote up
private void spannerWriteWithRetryIfSchemaChange(Iterable<Mutation> batch)
    throws SpannerException {
  for (int retry = 1; ; retry++) {
    try {
      spannerAccessor.getDatabaseClient().writeAtLeastOnce(batch);
      return;
    } catch (AbortedException e) {
      if (retry >= ABORTED_RETRY_ATTEMPTS) {
        throw e;
      }
      if (e.isRetryable() || e.getMessage().contains(errString)) {
        continue;
      }
      throw e;
    }
  }
}
 
Example #4
Source File: SpannerTransactionManagerTests.java    From spring-cloud-gcp with Apache License 2.0 6 votes vote down vote up
@Test
public void testDoCommitDupeException() {

	this.expectedEx.expect(DuplicateKeyException.class);
	this.expectedEx.expectMessage("ALREADY_EXISTS; nested exception is " +
			"com.google.cloud.spanner.SpannerException: ALREADY_EXISTS: this is from a test");

	SpannerException exception = SpannerExceptionFactory.newSpannerException(
			ErrorCode.ALREADY_EXISTS, "this is from a test");

	when(transactionManager.getState()).thenReturn(TransactionState.STARTED);
	Mockito.doThrow(exception).when(transactionManager).commit();

	tx.transactionManager = transactionManager;

	manager.doCommit(status);
}
 
Example #5
Source File: CloudSpannerConnection.java    From spanner-jdbc with MIT License 6 votes vote down vote up
/**
 * Execute one or more DDL-statements on the database and wait for it to finish or return after
 * syntax check (when running in async mode). Calling this method will also automatically commit
 * the currently running transaction.
 * 
 * @param inputSql The DDL-statement(s) to execute. Some statements may end up not being sent to
 *        Cloud Spanner if they contain IF [NOT] EXISTS clauses. The driver will check whether the
 *        condition is met, and only then will it be sent to Cloud Spanner.
 * @return Nothing
 * @throws SQLException If an error occurs during the execution of the statement.
 */
public Void executeDDL(List<String> inputSql) throws SQLException {
  if (!getAutoCommit())
    commit();
  // Check for IF [NOT] EXISTS statements
  List<String> sql = getActualSql(inputSql);
  if (!sql.isEmpty()) {
    try {
      Operation<Void, UpdateDatabaseDdlMetadata> operation =
          adminClient.updateDatabaseDdl(database.instance, database.database, sql, null);
      if (asyncDdlOperations) {
        operations.addOperation(sql, operation);
      } else {
        do {
          operation = operation.waitFor();
        } while (!operation.isDone());
      }
      return operation.getResult();
    } catch (SpannerException e) {
      throw new CloudSpannerSQLException("Could not execute DDL statement(s) "
          + String.join("\n;\n", sql) + ": " + e.getMessage(), e);
    }
  }
  return null;
}
 
Example #6
Source File: CloudSpannerResultSet.java    From spanner-jdbc with MIT License 6 votes vote down vote up
@Override
public boolean next() throws SQLException {
  ensureOpen();
  if (beforeFirst && nextCalledForInternalReasons) {
    currentRowIndex++;
    nextCalledForInternalReasons = false;
    beforeFirst = false;
    afterLast = !nextCalledForInternalReasonsResult;
    return nextCalledForInternalReasonsResult;
  }
  boolean res = false;
  try {
    res = resultSet.next();
  } catch (SpannerException e) {
    throw new CloudSpannerSQLException(e);
  }
  currentRowIndex++;
  beforeFirst = false;
  afterLast = !res;

  return res;
}
 
Example #7
Source File: Queue.java    From spanner-event-exporter with Apache License 2.0 6 votes vote down vote up
/**
 * Sends a QueueMessage to the spanner queue table
 *
 * <p>Example of sending data to a queue.
 *
 * <pre>{@code
 * MyProto myProto = MyProto.newBuilder().setMessage("My-Message").build();
 *
 * try {
 *   Queue.send(dbClient, queueName, "myKey", ByteArray.copyFrom(myProto.toByteArray()));
 * } catch (SpannerException e) {
 *   log.error("Could not write message to Queue", e);
 * }
 * }</pre>
 *
 * @param dbClient the Spanner database client
 * @param queueName the name of the queue to be polled
 * @param key the name used to partition the passed value for storage and lookup
 * @param value the message payload
 * @return Timestamp the timestamp that the message was written
 */
public static Timestamp send(DatabaseClient dbClient, String queueName, String key, byte[] value)
    throws SpannerException {
  Preconditions.checkNotNull(dbClient);
  Preconditions.checkNotNull(queueName);
  Preconditions.checkNotNull(key);
  Preconditions.checkNotNull(value);

  final List<Mutation> mutations = new ArrayList<>();
  mutations.add(
      Mutation.newInsertBuilder(queueName)
          .set("MessageId")
          .to(UUID.randomUUID().toString())
          .set("Key")
          .to(key)
          .set("Payload")
          .to(ByteArray.copyFrom(value))
          .set("Ack")
          .to(false)
          .set("Timestamp")
          .to(Value.COMMIT_TIMESTAMP)
          .build());

  return dbClient.write(mutations);
}
 
Example #8
Source File: CloudSpannerTransactionTest.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Test(expected = SpannerException.class)
public void testAnalyzeQuery() throws SQLException {
  CloudSpannerConnection connection = CloudSpannerTestObjects.createConnection();
  try (CloudSpannerTransaction tx = new CloudSpannerTransaction(null, null, connection)) {
    tx.analyzeQuery(null, null);
  }
}
 
Example #9
Source File: SpannerWriteIT.java    From java-docs-samples with Apache License 2.0 5 votes vote down vote up
@After
public void tearDown() {
  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Failed to cleanup.
  }

  spanner.close();
}
 
Example #10
Source File: SpannerReadIT.java    From java-docs-samples with Apache License 2.0 5 votes vote down vote up
@After
public void tearDown() {
  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Failed to cleanup.
  }

  spanner.close();
}
 
Example #11
Source File: SpannerGroupWriteIT.java    From java-docs-samples with Apache License 2.0 5 votes vote down vote up
@After
public void tearDown() {
  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Failed to cleanup.
  }

  spanner.close();
}
 
Example #12
Source File: SpannerServerResource.java    From DataflowTemplates with Apache License 2.0 5 votes vote down vote up
public void dropDatabase(String dbName) {
  try {
    databaseAdminClient.dropDatabase(instanceId, dbName);
  } catch (SpannerException e) {
    // Does not exist, ignore.
  }
}
 
Example #13
Source File: SpannerTransactionManager.java    From spring-cloud-gcp with Apache License 2.0 5 votes vote down vote up
private RuntimeException makeDataIntegrityViolationException(SpannerException e) {
	switch (e.getErrorCode()) {
	case ALREADY_EXISTS:
		return new DuplicateKeyException(e.getErrorCode().toString(), e);
	}
	return e;
}
 
Example #14
Source File: CloudSpannerTransaction.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public List<Partition> partitionQuery(PartitionOptions partitionOptions, Statement statement,
    QueryOption... options) throws SpannerException {
  checkTransaction();
  if (batchReadOnlyTransaction != null) {
    return batchReadOnlyTransaction.partitionQuery(partitionOptions, statement, options);
  }
  throw SpannerExceptionFactory.newSpannerException(ErrorCode.FAILED_PRECONDITION,
      METHOD_ONLY_IN_BATCH_READONLY);
}
 
Example #15
Source File: CloudSpannerTransactionTest.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Test(expected = SpannerException.class)
public void testReadRowUsingIndex() throws SQLException {
  CloudSpannerConnection connection = CloudSpannerTestObjects.createConnection();
  try (CloudSpannerTransaction tx = new CloudSpannerTransaction(null, null, connection)) {
    tx.readRowUsingIndex(null, null, null, null);
  }
}
 
Example #16
Source File: CloudSpannerTransactionTest.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Test(expected = SpannerException.class)
public void testReadRow() throws SQLException {
  CloudSpannerConnection connection = CloudSpannerTestObjects.createConnection();
  try (CloudSpannerTransaction tx = new CloudSpannerTransaction(null, null, connection)) {
    tx.readRow(null, null, null);
  }
}
 
Example #17
Source File: CloudSpannerTransactionTest.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Test(expected = SpannerException.class)
public void testReadUsingIndex() throws SQLException {
  CloudSpannerConnection connection = CloudSpannerTestObjects.createConnection();
  try (CloudSpannerTransaction tx = new CloudSpannerTransaction(null, null, connection)) {
    tx.readUsingIndex(null, null, null, null);
  }
}
 
Example #18
Source File: CloudSpannerTransactionTest.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Test(expected = SpannerException.class)
public void testRead() throws SQLException {
  CloudSpannerConnection connection = CloudSpannerTestObjects.createConnection();
  try (CloudSpannerTransaction tx = new CloudSpannerTransaction(null, null, connection)) {
    tx.read(null, null, null);
  }
}
 
Example #19
Source File: AbstractCloudSpannerStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
protected long writeMutations(Mutations mutations) throws SQLException {
  if (connection.isReadOnly()) {
    throw new CloudSpannerSQLException(NO_MUTATIONS_IN_READ_ONLY_MODE_EXCEPTION,
        Code.FAILED_PRECONDITION);
  }
  if (mutations.isWorker()) {
    ConversionResult result = mutations.getWorker().call();
    if (result.getException() != null) {
      if (result.getException() instanceof SQLException)
        throw (SQLException) result.getException();
      if (result.getException() instanceof SpannerException)
        throw new CloudSpannerSQLException((SpannerException) result.getException());
      throw new CloudSpannerSQLException(result.getException().getMessage(), Code.UNKNOWN,
          result.getException());
    }
  } else {

    if (connection.getAutoCommit()) {
      dbClient.readWriteTransaction().run(new TransactionCallable<Void>() {

        @Override
        public Void run(TransactionContext transaction) throws Exception {
          transaction.buffer(mutations.getMutations());
          return null;
        }
      });
    } else {
      connection.getTransaction().buffer(mutations.getMutations());
    }
  }
  return mutations.getNumberOfResults();
}
 
Example #20
Source File: CloudSpannerTransaction.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public List<Partition> partitionReadUsingIndex(PartitionOptions partitionOptions, String table,
    String index, KeySet keys, Iterable<String> columns, ReadOption... options)
    throws SpannerException {
  throw SpannerExceptionFactory.newSpannerException(ErrorCode.UNIMPLEMENTED,
      METHOD_NOT_IMPLEMENTED);
}
 
Example #21
Source File: CloudSpannerResultSet.java    From spanner-jdbc with MIT License 5 votes vote down vote up
/**
 * Advances the underlying {@link com.google.cloud.spanner.ResultSet} to the first position. This
 * forces the query to be executed, and ensures that any invalid queries are reported as quickly
 * as possible.
 * 
 * @throws CloudSpannerSQLException
 */
private void callNextForInternalReasons() throws CloudSpannerSQLException {
  if (!nextCalledForInternalReasons) {
    try {
      nextCalledForInternalReasonsResult = resultSet.next();
    } catch (SpannerException e) {
      throw new CloudSpannerSQLException(e);
    }
    nextCalledForInternalReasons = true;
  }
}
 
Example #22
Source File: CloudSpannerTransaction.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public ResultSet execute(Partition partition) throws SpannerException {
  checkTransaction();
  if (batchReadOnlyTransaction != null) {
    return batchReadOnlyTransaction.execute(partition);
  }
  throw SpannerExceptionFactory.newSpannerException(ErrorCode.FAILED_PRECONDITION,
      METHOD_ONLY_IN_BATCH_READONLY);
}
 
Example #23
Source File: CloudSpannerTransaction.java    From spanner-jdbc with MIT License 4 votes vote down vote up
@Override
public List<Partition> partitionRead(PartitionOptions partitionOptions, String table, KeySet keys,
    Iterable<String> columns, ReadOption... options) throws SpannerException {
  throw SpannerExceptionFactory.newSpannerException(ErrorCode.UNIMPLEMENTED,
      METHOD_NOT_IMPLEMENTED);
}
 
Example #24
Source File: CloudSpannerSQLException.java    From spanner-jdbc with MIT License 4 votes vote down vote up
public CloudSpannerSQLException(String message, SpannerException e) {
  super(message, null, e.getCode(), e);
  this.code = Code.forNumber(e.getCode());
}
 
Example #25
Source File: LocalSpannerIO.java    From DataflowTemplates with Apache License 2.0 4 votes vote down vote up
/** Write the Mutations to Spanner, handling DEADLINE_EXCEEDED with backoff/retries. */
private void writeMutations(Iterable<Mutation> mutations) throws SpannerException, IOException {
  BackOff backoff = bundleWriteBackoff.backoff();
  long mutationsSize = Iterables.size(mutations);

  while (true) {
    Stopwatch timer = Stopwatch.createStarted();
    // loop is broken on success, timeout backoff/retry attempts exceeded, or other failure.
    try {
      spannerWriteWithRetryIfSchemaChange(mutations);
      spannerWriteSuccess.inc();
      return;
    } catch (SpannerException exception) {
      if (exception.getErrorCode() == ErrorCode.DEADLINE_EXCEEDED) {
        spannerWriteTimeouts.inc();

        // Potentially backoff/retry after DEADLINE_EXCEEDED.
        long sleepTimeMsecs = backoff.nextBackOffMillis();
        if (sleepTimeMsecs == BackOff.STOP) {
          LOG.error(
              "DEADLINE_EXCEEDED writing batch of {} mutations to Cloud Spanner. "
                  + "Aborting after too many retries.",
              mutationsSize);
          spannerWriteFail.inc();
          throw exception;
        }
        LOG.info(
            "DEADLINE_EXCEEDED writing batch of {} mutations to Cloud Spanner, "
                + "retrying after backoff of {}ms\n"
                + "({})",
            mutationsSize,
            sleepTimeMsecs,
            exception.getMessage());
        spannerWriteRetries.inc();
        try {
          sleeper.sleep(sleepTimeMsecs);
        } catch (InterruptedException e) {
          // ignore.
        }
      } else {
        // Some other failure: pass up the stack.
        spannerWriteFail.inc();
        throw exception;
      }
    } finally {
      spannerWriteLatency.update(timer.elapsed(TimeUnit.MILLISECONDS));
    }
  }
}
 
Example #26
Source File: SpannerIO.java    From beam with Apache License 2.0 4 votes vote down vote up
/** Write the Mutations to Spanner, handling DEADLINE_EXCEEDED with backoff/retries. */
private void writeMutations(Iterable<Mutation> mutations) throws SpannerException, IOException {
  BackOff backoff = bundleWriteBackoff.backoff();
  long mutationsSize = Iterables.size(mutations);

  while (true) {
    Stopwatch timer = Stopwatch.createStarted();
    // loop is broken on success, timeout backoff/retry attempts exceeded, or other failure.
    try {
      spannerWriteWithRetryIfSchemaChange(mutations);
      spannerWriteSuccess.inc();
      return;
    } catch (SpannerException exception) {
      if (exception.getErrorCode() == ErrorCode.DEADLINE_EXCEEDED) {
        spannerWriteTimeouts.inc();

        // Potentially backoff/retry after DEADLINE_EXCEEDED.
        long sleepTimeMsecs = backoff.nextBackOffMillis();
        if (sleepTimeMsecs == BackOff.STOP) {
          LOG.error(
              "DEADLINE_EXCEEDED writing batch of {} mutations to Cloud Spanner. "
                  + "Aborting after too many retries.",
              mutationsSize);
          spannerWriteFail.inc();
          throw exception;
        }
        LOG.info(
            "DEADLINE_EXCEEDED writing batch of {} mutations to Cloud Spanner, "
                + "retrying after backoff of {}ms\n"
                + "({})",
            mutationsSize,
            sleepTimeMsecs,
            exception.getMessage());
        spannerWriteRetries.inc();
        try {
          sleeper.sleep(sleepTimeMsecs);
        } catch (InterruptedException e) {
          // ignore.
        }
      } else {
        // Some other failure: pass up the stack.
        spannerWriteFail.inc();
        throw exception;
      }
    } finally {
      spannerWriteLatency.update(timer.elapsed(TimeUnit.MILLISECONDS));
    }
  }
}
 
Example #27
Source File: SpannerGroupWriteIT.java    From java-docs-samples with Apache License 2.0 4 votes vote down vote up
@Before
public void setUp() throws Exception {
  instanceId = System.getProperty("spanner.test.instance");
  databaseId = "df-spanner-gwrite-it-" + random.nextInt(1000000000);

  spannerOptions = SpannerOptions.getDefaultInstance();
  spanner = spannerOptions.getService();

  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();

  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Does not exist, ignore.
  }

  OperationFuture<Database, CreateDatabaseMetadata> op =
      adminClient.createDatabase(
          instanceId,
          databaseId,
          Arrays.asList(
              "CREATE TABLE users ("
                  + "id STRING(MAX) NOT NULL, state STRING(MAX) NOT NULL) PRIMARY KEY (id)",
              "CREATE TABLE PendingReviews (id INT64, action STRING(MAX), "
                  + "note STRING(MAX), userId STRING(MAX),) PRIMARY KEY (id)"));

  op.get();

  DatabaseClient dbClient = getDbClient();

  List<Mutation> mutations = new ArrayList<>();
  for (int i = 0; i < 20; i++) {
    mutations.add(
        Mutation.newInsertBuilder("users")
            .set("id")
            .to(Integer.toString(i))
            .set("state")
            .to("ACTIVE")
            .build());
  }
  TransactionRunner runner = dbClient.readWriteTransaction();
  runner.run(
      new TransactionRunner.TransactionCallable<Void>() {

        @Nullable
        @Override
        public Void run(TransactionContext tx) {
          tx.buffer(mutations);
          return null;
        }
      });

  String content =
      IntStream.range(0, 10).mapToObj(Integer::toString).collect(Collectors.joining("\n"));
  tempPath = Files.createTempFile("suspicious-ids", "txt");
  Files.write(tempPath, content.getBytes());
}
 
Example #28
Source File: CloudSpannerSQLException.java    From spanner-jdbc with MIT License 4 votes vote down vote up
public CloudSpannerSQLException(SpannerException e) {
  super(e.getMessage(), null, e.getCode(), e);
  this.code = Code.forNumber(e.getCode());
}
 
Example #29
Source File: SpannerReadIT.java    From java-docs-samples with Apache License 2.0 4 votes vote down vote up
@Before
public void setUp() throws InterruptedException, ExecutionException {
  instanceId = System.getProperty("spanner.test.instance");
  databaseId = "df-spanner-read-it-" + random.nextInt(1000000000);

  spannerOptions = SpannerOptions.getDefaultInstance();
  spanner = spannerOptions.getService();

  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();

  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Does not exist, ignore.
  }

  OperationFuture<Database, CreateDatabaseMetadata> op =
      adminClient.createDatabase(
          instanceId,
          databaseId,
          Arrays.asList(
              "CREATE TABLE Singers "
                  + "(singerId INT64 NOT NULL, firstName STRING(MAX) NOT NULL, "
                  + "lastName STRING(MAX) NOT NULL,) PRIMARY KEY (singerId)",
              "CREATE TABLE Albums (singerId INT64 NOT NULL, albumId INT64 NOT NULL, "
                  + "albumTitle STRING(MAX) NOT NULL,) PRIMARY KEY (singerId, albumId)"));

  op.get();

  List<Mutation> mutations =
      Arrays.asList(
          Mutation.newInsertBuilder("singers")
              .set("singerId")
              .to(1L)
              .set("firstName")
              .to("John")
              .set("lastName")
              .to("Lennon")
              .build(),
          Mutation.newInsertBuilder("singers")
              .set("singerId")
              .to(2L)
              .set("firstName")
              .to("Paul")
              .set("lastName")
              .to("Mccartney")
              .build(),
          Mutation.newInsertBuilder("singers")
              .set("singerId")
              .to(3L)
              .set("firstName")
              .to("George")
              .set("lastName")
              .to("Harrison")
              .build(),
          Mutation.newInsertBuilder("singers")
              .set("singerId")
              .to(4L)
              .set("firstName")
              .to("Ringo")
              .set("lastName")
              .to("Starr")
              .build(),
          Mutation.newInsertBuilder("albums")
              .set("singerId")
              .to(1L)
              .set("albumId")
              .to(1L)
              .set("albumTitle")
              .to("Imagine")
              .build(),
          Mutation.newInsertBuilder("albums")
              .set("singerId")
              .to(2L)
              .set("albumId")
              .to(1L)
              .set("albumTitle")
              .to("Pipes of Peace")
              .build());

  DatabaseClient dbClient = getDbClient();

  TransactionRunner runner = dbClient.readWriteTransaction();
  runner.run(
      new TransactionRunner.TransactionCallable<Void>() {
        @Nullable
        @Override
        public Void run(TransactionContext tx) {
          tx.buffer(mutations);
          return null;
        }
      });
}
 
Example #30
Source File: SpannerWriteIT.java    From java-docs-samples with Apache License 2.0 4 votes vote down vote up
@Before
public void setUp() throws Exception {

  instanceId = System.getProperty("spanner.test.instance");
  databaseId = "df-spanner-write-it-" + random.nextInt(1000000000);

  spannerOptions = SpannerOptions.getDefaultInstance();
  spanner = spannerOptions.getService();

  DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();

  try {
    adminClient.dropDatabase(instanceId, databaseId);
  } catch (SpannerException e) {
    // Does not exist, ignore.
  }

  OperationFuture<Database, CreateDatabaseMetadata> op =
      adminClient.createDatabase(
          instanceId,
          databaseId,
          Arrays.asList(
              "CREATE TABLE Singers "
                  + "(singerId INT64 NOT NULL, "
                  + "firstName STRING(MAX) NOT NULL, lastName STRING(MAX) NOT NULL,) "
                  + "PRIMARY KEY (singerId)",
              "CREATE TABLE Albums (singerId INT64 NOT NULL, "
                  + "albumId INT64 NOT NULL, albumTitle STRING(MAX) NOT NULL,) "
                  + "PRIMARY KEY (singerId, albumId)"));

  op.get();

  String singers =
      Stream.of("1\tJohn\tLennon", "2\tPaul\tMccartney", "3\tGeorge\tHarrison", "4\tRingo\tStarr")
          .collect(Collectors.joining("\n"));
  singersPath = Files.createTempFile("singers", "txt");
  Files.write(singersPath, singers.getBytes());

  String albums =
      Stream.of("1\t1\tImagine", "2\t1\tPipes of Peace", "3\t1\tDark Horse")
          .collect(Collectors.joining("\n"));
  albumsPath = Files.createTempFile("albums", "txt");
  Files.write(albumsPath, albums.getBytes());
}