Skip to content

Commit

Permalink
incorporate requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
rahul2393 committed Jul 7, 2022
1 parent 7140356 commit ce34d5b
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 147 deletions.
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -41,7 +41,7 @@ If you are using Maven without BOM, add this to your dependencies:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
<version>6.25.5</version>
<version>6.25.8</version>
</dependency>

```
Expand All @@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-spanner'
If you are using Gradle without BOM, add this to your dependencies

```Groovy
implementation 'com.google.cloud:google-cloud-spanner:6.25.6'
implementation 'com.google.cloud:google-cloud-spanner:6.25.8'
```

If you are using SBT, add this to your dependencies

```Scala
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.25.6"
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.25.8"
```

## Authentication
Expand Down
Expand Up @@ -834,7 +834,12 @@ public Builder setSessionPoolOption(SessionPoolOptions sessionPoolOptions) {
return this;
}

/** Sets the database role that should be used by this instance. */
/**
* Sets the database role that should be used for connections that are created by this instance.
* The database role that is used determines the access permissions that a connection has. This
* can for example be used to create connections that are only permitted to access certain
* tables.
*/
public Builder setDatabaseRole(String databaseRole) {
this.databaseRole = databaseRole;
return this;
Expand Down
Expand Up @@ -214,6 +214,8 @@ public String[] getValidValues() {
public static final String LENIENT_PROPERTY_NAME = "lenient";
/** Name of the 'rpcPriority' connection property. */
public static final String RPC_PRIORITY_NAME = "rpcPriority";
/** Dialect to use for a connection. */
private static final String DIALECT_PROPERTY_NAME = "dialect";
/** Name of the 'databaseRole' connection property. */
public static final String DATABASE_ROLE_PROPERTY_NAME = "databaseRole";

Expand Down Expand Up @@ -282,6 +284,8 @@ public String[] getValidValues() {
ConnectionProperty.createStringProperty(
RPC_PRIORITY_NAME,
"Sets the priority for all RPC invocations from this connection (HIGH/MEDIUM/LOW). The default is HIGH."),
ConnectionProperty.createStringProperty(
DIALECT_PROPERTY_NAME, "Sets the dialect to use for this connection."),
ConnectionProperty.createStringProperty(
DATABASE_ROLE_PROPERTY_NAME,
"Sets the database role to use for this connection. The default is privileges assigned to IAM role"))));
Expand Down Expand Up @@ -969,7 +973,10 @@ public TransportChannelProvider getChannelProvider() {
}
}

/** The creator role to use for the connection. */
/**
* The database role that is used for this connection. Assigning a role to a connection can be
* used to for example restrict the access of a connection to a specific set of tables.
*/
public String getDatabaseRole() {
return databaseRole;
}
Expand Down
Expand Up @@ -50,7 +50,7 @@ public class RemoteSpannerHelper {
private final InstanceId instanceId;
private static final AtomicInteger dbSeq = new AtomicInteger();
private static final int dbPrefix = new Random().nextInt(Integer.MAX_VALUE);
private static int dbRoleSeq;
private static final AtomicInteger dbRoleSeq = new AtomicInteger();;
private static int dbRolePrefix = new Random().nextInt(Integer.MAX_VALUE);
private static final AtomicInteger backupSeq = new AtomicInteger();
private static final int backupPrefix = new Random().nextInt(Integer.MAX_VALUE);
Expand Down Expand Up @@ -114,7 +114,7 @@ public String getUniqueDatabaseId() {
* environment.
*/
public String getUniqueDatabaseRole() {
return String.format("testdbrole_%d_%04d", dbRolePrefix, dbRoleSeq++);
return String.format("testdbrole_%d_%04d", dbRolePrefix, dbRoleSeq.incrementAndGet());
}

/**
Expand Down
Expand Up @@ -119,13 +119,14 @@ public void createAndCloseSession() {
labels.put("env", "dev");
String databaseRole = "role";
when(spannerOptions.getSessionLabels()).thenReturn(labels);
when(spannerOptions.getDatabaseRole()).thenReturn(databaseRole);
when(spannerOptions.getDatabaseRole()).thenReturn(databaseRole);
com.google.spanner.v1.Session sessionProto =
com.google.spanner.v1.Session.newBuilder()
.setName(sessionName)
.putAllLabels(labels)
.build();
when(rpc.createSession(Mockito.eq(dbName),Mockito.eq(databaseRole), Mockito.eq(labels), options.capture()))
when(rpc.createSession(
Mockito.eq(dbName), Mockito.eq(databaseRole), Mockito.eq(labels), options.capture()))
.thenReturn(sessionProto);

try (SessionClient client = new SessionClient(spanner, db, new TestExecutorFactory())) {
Expand All @@ -145,13 +146,17 @@ public void batchCreateAndCloseSessions() {
final String sessionName = dbName + "/sessions/s%d";
final Map<String, String> labels = new HashMap<>();
labels.put("env", "dev");
String databaseRole = new String("role");
String databaseRole = new String("role");
when(spannerOptions.getSessionLabels()).thenReturn(labels);
when(spannerOptions.getDatabaseRole()).thenReturn(databaseRole);
when(spannerOptions.getDatabaseRole()).thenReturn(databaseRole);

final List<Long> usedChannels = Collections.synchronizedList(new ArrayList<>());
final List<Long> usedChannels = Collections.synchronizedList(new ArrayList<>());
when(rpc.batchCreateSessions(
Mockito.eq(dbName), Mockito.anyInt(),Mockito.eq(databaseRole), Mockito.eq(labels), Mockito.anyMap()))
Mockito.eq(dbName),
Mockito.anyInt(),
Mockito.eq(databaseRole),
Mockito.eq(labels),
Mockito.anyMap()))
.then(
invocation -> {
Map<Option, Object> options = invocation.getArgument(4, Map.class);
Expand Down Expand Up @@ -209,10 +214,14 @@ public void batchCreateSessionsDistributesMultipleRequestsOverChannels() {
final String sessionName = dbName + "/sessions/s%d";
final Map<String, String> labels = Collections.emptyMap();
when(spannerOptions.getSessionLabels()).thenReturn(labels);
when(spannerOptions.getDatabaseRole()).thenReturn("role");
when(spannerOptions.getDatabaseRole()).thenReturn("role");
final Set<Long> usedChannelHints = Collections.synchronizedSet(new HashSet<>());
when(rpc.batchCreateSessions(
Mockito.eq(dbName), Mockito.anyInt(),Mockito.anyString(), Mockito.eq(labels), Mockito.anyMap()))
Mockito.eq(dbName),
Mockito.anyInt(),
Mockito.anyString(),
Mockito.eq(labels),
Mockito.anyMap()))
.then(
invocation -> {
Map<Option, Object> options = invocation.getArgument(4, Map.class);
Expand All @@ -225,7 +234,7 @@ public void batchCreateSessionsDistributesMultipleRequestsOverChannels() {
com.google.spanner.v1.Session.newBuilder()
.setName(String.format(sessionName, i))
.putAllLabels(labels)
.setCreatorRole("role")
.setCreatorRole("role")
.build());
}
return res;
Expand Down Expand Up @@ -294,7 +303,11 @@ public void batchCreateSessionsWithExceptions() {
DatabaseId db = DatabaseId.of(dbName);
final String sessionName = dbName + "/sessions/s%d";
when(rpc.batchCreateSessions(
Mockito.eq(dbName), Mockito.anyInt(),Mockito.anyString(), Mockito.anyMap(), Mockito.anyMap()))
Mockito.eq(dbName),
Mockito.anyInt(),
Mockito.anyString(),
Mockito.anyMap(),
Mockito.anyMap()))
.then(
invocation -> {
Map<Option, Object> options = invocation.getArgument(4, Map.class);
Expand Down Expand Up @@ -358,7 +371,11 @@ public void batchCreateSessionsServerReturnsLessSessionsPerBatch() {
DatabaseId db = DatabaseId.of(dbName);
final String sessionName = dbName + "/sessions/s%d";
when(rpc.batchCreateSessions(
Mockito.eq(dbName), Mockito.anyInt(),Mockito.anyString(), Mockito.anyMap(), Mockito.anyMap()))
Mockito.eq(dbName),
Mockito.anyInt(),
Mockito.anyString(),
Mockito.anyMap(),
Mockito.anyMap()))
.then(
invocation -> {
int sessionCount = invocation.getArgument(1, Integer.class);
Expand Down
Expand Up @@ -95,7 +95,7 @@ public void setUp() {
Session sessionProto = Session.newBuilder().setName(sessionName).build();
Mockito.when(
rpc.createSession(
Mockito.eq(dbName), Mockito.anyString(), Mockito.anyMap(), optionsCaptor.capture()))
Mockito.eq(dbName), Mockito.anyString(), Mockito.anyMap(), optionsCaptor.capture()))
.thenReturn(sessionProto);
Transaction txn = Transaction.newBuilder().setId(ByteString.copyFromUtf8("TEST")).build();
Mockito.when(
Expand Down
Expand Up @@ -140,7 +140,7 @@ public void setUp() {
when(client.getOptions()).thenReturn(spannerOptions);
when(client.getSessionClient(db)).thenReturn(sessionClient);
when(spannerOptions.getNumChannels()).thenReturn(4);
when(spannerOptions.getDatabaseRole()).thenReturn("role");
when(spannerOptions.getDatabaseRole()).thenReturn("role");
options =
SessionPoolOptions.newBuilder()
.setMinSessions(minSessions)
Expand Down Expand Up @@ -848,8 +848,8 @@ public void testSessionNotFoundReadWriteTransaction() {
SpannerOptions spannerOptions = mock(SpannerOptions.class);
when(spannerOptions.getSessionPoolOptions()).thenReturn(options);
when(spannerOptions.getNumChannels()).thenReturn(4);
when(spannerOptions.getDatabaseRole()).thenReturn("role");
when(spanner.getOptions()).thenReturn(spannerOptions);
when(spannerOptions.getDatabaseRole()).thenReturn("role");
when(spanner.getOptions()).thenReturn(spannerOptions);
SessionPool pool =
SessionPool.createPool(options, new TestExecutorFactory(), spanner.getSessionClient(db));
try (PooledSessionFuture readWriteSession = pool.getSession()) {
Expand Down
Expand Up @@ -76,7 +76,7 @@ public void defaultBuilder() {
// id.
SpannerOptions options = SpannerOptions.newBuilder().setProjectId("test-project").build();
if (Strings.isNullOrEmpty(System.getenv("SPANNER_EMULATOR_HOST"))) {
assertThat(options.getHost()).isEqualTo("https://staging-wrenchworks.sandbox.googleapis.com/");
assertThat(options.getHost()).isEqualTo("https://spanner.googleapis.com");
} else {
assertThat(options.getHost()).isEqualTo("http://" + System.getenv("SPANNER_EMULATOR_HOST"));
}
Expand Down
Expand Up @@ -203,7 +203,11 @@ public void usesPreparedTransaction() {
when(rpc.asyncDeleteSession(Mockito.anyString(), Mockito.anyMap()))
.thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance()));
when(rpc.batchCreateSessions(
Mockito.anyString(), Mockito.eq(1), Mockito.anyString(),Mockito.anyMap(), Mockito.anyMap()))
Mockito.anyString(),
Mockito.eq(1),
Mockito.anyString(),
Mockito.anyMap(),
Mockito.anyMap()))
.thenAnswer(
invocation ->
Collections.singletonList(
Expand Down Expand Up @@ -260,7 +264,11 @@ public void inlineBegin() {
when(rpc.asyncDeleteSession(Mockito.anyString(), Mockito.anyMap()))
.thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance()));
when(rpc.batchCreateSessions(
Mockito.anyString(), Mockito.eq(1),Mockito.anyString(), Mockito.anyMap(), Mockito.anyMap()))
Mockito.anyString(),
Mockito.eq(1),
Mockito.anyString(),
Mockito.anyMap(),
Mockito.anyMap()))
.thenAnswer(
invocation ->
Collections.singletonList(
Expand Down
Expand Up @@ -147,7 +147,11 @@ public void usesPreparedTransaction() {
when(rpc.asyncDeleteSession(Mockito.anyString(), Mockito.anyMap()))
.thenReturn(ApiFutures.immediateFuture(Empty.getDefaultInstance()));
when(rpc.batchCreateSessions(
Mockito.anyString(), Mockito.eq(1),Mockito.anyString(), Mockito.anyMap(), Mockito.anyMap()))
Mockito.anyString(),
Mockito.eq(1),
Mockito.anyString(),
Mockito.anyMap(),
Mockito.anyMap()))
.thenAnswer(
invocation ->
Collections.singletonList(
Expand Down
Expand Up @@ -24,8 +24,8 @@
import com.google.api.gax.longrunning.OperationFuture;
import com.google.api.gax.paging.Page;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseRole;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseRole;
import com.google.cloud.spanner.Dialect;
import com.google.cloud.spanner.ErrorCode;
import com.google.cloud.spanner.IntegrationTestEnv;
Expand Down Expand Up @@ -210,30 +210,30 @@ public void listPagination() throws Exception {
@Test
public void createAndListDatabaseRoles() throws Exception {
List<String> dbRoles =
ImmutableList.of(
testHelper.getUniqueDatabaseRole(),
testHelper.getUniqueDatabaseRole(),
testHelper.getUniqueDatabaseRole());
ImmutableList.of(
testHelper.getUniqueDatabaseRole(),
testHelper.getUniqueDatabaseRole(),
testHelper.getUniqueDatabaseRole());

String instanceId = testHelper.getInstanceId().getInstance();
Database database =
dbAdminClient
.createDatabase(instanceId, testHelper.getUniqueDatabaseId(), ImmutableList.of())
.get();
dbAdminClient
.createDatabase(instanceId, testHelper.getUniqueDatabaseId(), ImmutableList.of())
.get();

// Create the roles in Db.
List<String> dbRolesCreateStatements = new ArrayList<>();
for (String dbRole : dbRoles) {
dbRolesCreateStatements.add(String.format("CREATE ROLE %s", dbRole));
}
dbAdminClient
.updateDatabaseDdl(
instanceId, database.getId().getDatabase(), dbRolesCreateStatements, null)
.get();
.updateDatabaseDdl(
instanceId, database.getId().getDatabase(), dbRolesCreateStatements, null)
.get();

// List roles from Db.
Page<DatabaseRole> page =
dbAdminClient.listDatabaseRoles(instanceId, database.getId().getDatabase());
dbAdminClient.listDatabaseRoles(instanceId, database.getId().getDatabase());
List<String> dbRolesGot = new ArrayList<>();
while (page != null && page.getValues().iterator().hasNext()) {
for (DatabaseRole value : page.getValues()) {
Expand All @@ -250,12 +250,12 @@ public void createAndListDatabaseRoles() throws Exception {
dbRolesDropStatements.add(String.format("DROP ROLE %s", dbRole));
}
dbAdminClient
.updateDatabaseDdl(instanceId, database.getId().getDatabase(), dbRolesDropStatements, null)
.get();
.updateDatabaseDdl(instanceId, database.getId().getDatabase(), dbRolesDropStatements, null)
.get();

// List roles from Db. Deleted roles should not be present in list.
Page<DatabaseRole> pageRemainingRoles =
dbAdminClient.listDatabaseRoles(instanceId, database.getId().getDatabase());
dbAdminClient.listDatabaseRoles(instanceId, database.getId().getDatabase());
List<String> dbRolesRemaining = new ArrayList<>();
while (pageRemainingRoles != null && pageRemainingRoles.getValues().iterator().hasNext()) {
for (DatabaseRole value : pageRemainingRoles.getValues()) {
Expand Down

0 comments on commit ce34d5b

Please sign in to comment.