diff --git a/modules/gcloud/build.gradle b/modules/gcloud/build.gradle index a5737648a4b..aa42d7dc560 100644 --- a/modules/gcloud/build.gradle +++ b/modules/gcloud/build.gradle @@ -7,5 +7,6 @@ dependencies { testCompile 'com.google.cloud:google-cloud-firestore:1.33.0' testCompile 'com.google.cloud:google-cloud-pubsub:1.105.0' testCompile 'com.google.cloud:google-cloud-spanner:1.50.0' + testCompile 'com.google.cloud:google-cloud-bigtable:1.17.3' testCompile 'org.assertj:assertj-core:3.15.0' } diff --git a/modules/gcloud/src/main/java/org/testcontainers/containers/BigtableEmulatorContainer.java b/modules/gcloud/src/main/java/org/testcontainers/containers/BigtableEmulatorContainer.java new file mode 100644 index 00000000000..4b81e3964ce --- /dev/null +++ b/modules/gcloud/src/main/java/org/testcontainers/containers/BigtableEmulatorContainer.java @@ -0,0 +1,44 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +/** + * A Bigtable container that relies in google cloud sdk. + * + * Default port is 9000. + * + * @author EddĂș MelĂ©ndez + * @author Ray Tsang + */ +public class BigtableEmulatorContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk"); + + private static final String CMD = "gcloud beta emulators bigtable start --host-port 0.0.0.0:9000"; + private static final int PORT = 9000; + + public BigtableEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + + withExposedPorts(PORT); + setWaitStrategy(new LogMessageWaitStrategy() + .withRegEx("(?s).*running.*$")); + withCommand("/bin/sh", "-c", CMD); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator is + * reachable from the test host machine. Directly usable as a parameter to the + * com.google.cloud.ServiceOptions.Builder#setHost(java.lang.String) method. + */ + public String getEmulatorEndpoint() { + return getHost() + ":" + getEmulatorPort(); + } + + public int getEmulatorPort() { + return getMappedPort(PORT); + } +} diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java new file mode 100644 index 00000000000..0cc44afcc77 --- /dev/null +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java @@ -0,0 +1,95 @@ +package org.testcontainers.containers; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.api.core.ApiFuture; +import com.google.api.gax.batching.Batcher; +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.bigtable.admin.v2.BigtableInstanceAdminClient; +import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient; +import com.google.cloud.bigtable.admin.v2.models.CreateInstanceRequest; +import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest; +import com.google.cloud.bigtable.admin.v2.models.Instance; +import com.google.cloud.bigtable.admin.v2.models.Table; +import com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStub; +import com.google.cloud.bigtable.admin.v2.stub.BigtableInstanceAdminStubSettings; +import com.google.cloud.bigtable.admin.v2.stub.BigtableTableAdminStubSettings; +import com.google.cloud.bigtable.admin.v2.stub.EnhancedBigtableTableAdminStub; +import com.google.cloud.bigtable.data.v2.BigtableDataClient; +import com.google.cloud.bigtable.data.v2.BigtableDataSettings; +import com.google.cloud.bigtable.data.v2.models.Row; +import com.google.cloud.bigtable.data.v2.models.RowCell; +import com.google.cloud.bigtable.data.v2.models.RowMutation; +import com.google.cloud.bigtable.data.v2.models.RowMutationEntry; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class BigtableEmulatorContainerTest { + + public static final String PROJECT_ID = "test-project"; + public static final String INSTANCE_ID = "test-instance"; + + @Rule + // emulatorContainer { + public BigtableEmulatorContainer emulator = new BigtableEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:316.0.0-emulators") + ); + // } + + @Test + // testWithEmulatorContainer { + public void testSimple() throws IOException, InterruptedException, ExecutionException { + ManagedChannel channel = ManagedChannelBuilder.forTarget(emulator.getEmulatorEndpoint()) + .usePlaintext().build(); + + TransportChannelProvider channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel)); + NoCredentialsProvider credentialsProvider = NoCredentialsProvider.create(); + + try { + createTable(channelProvider, credentialsProvider, "test-table" ); + + BigtableDataClient client = BigtableDataClient.create(BigtableDataSettings + .newBuilderForEmulator(emulator.getHost(), emulator.getEmulatorPort()) + .setProjectId(PROJECT_ID) + .setInstanceId(INSTANCE_ID) + .build()); + + client.mutateRow(RowMutation.create("test-table", "1") + .setCell("name", "firstName", "Ray")); + + Row row = client.readRow("test-table", "1"); + List cells = row.getCells("name", "firstName"); + + assertThat(cells).isNotNull().hasSize(1); + assertThat(cells.get(0).getValue().toStringUtf8()).isEqualTo("Ray"); + } finally { + channel.shutdown(); + } + } + // } + + // createTable { + private void createTable(TransportChannelProvider channelProvider, CredentialsProvider credentialsProvider, String tableName) throws IOException { + EnhancedBigtableTableAdminStub stub = EnhancedBigtableTableAdminStub + .createEnhanced(BigtableTableAdminStubSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .build()); + + try (BigtableTableAdminClient client = BigtableTableAdminClient.create(PROJECT_ID, INSTANCE_ID, stub)) { + Table table = client.createTable(CreateTableRequest.of(tableName).addFamily("name")); + } + } + // } +}