Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.api.core.ApiFunction;
import com.google.api.services.bigquery.model.Dataset.Access;
import com.google.api.services.bigquery.model.DatasetAccessEntry;
import com.google.api.services.bigquery.model.Expr;
import com.google.cloud.StringEnumType;
import com.google.cloud.StringEnumValue;
import java.io.Serializable;
Expand All @@ -41,6 +42,7 @@ public final class Acl implements Serializable {

private final Entity entity;
private final Role role;
private final Expr condition;

/**
* Dataset roles supported by BigQuery.
Expand Down Expand Up @@ -568,9 +570,82 @@ Access toPb() {
}
}

/** Expr represents the conditional information related to dataset access policies. */
public static final class Expr implements Serializable {
// Textual representation of an expression in Common Expression Language syntax.
private final String expression;
/**
* Optional. Title for the expression, i.e. a short string describing its purpose. This can be
* used e.g. in UIs which allow to enter the expression.
*/
private final String title;
/**
* Optional. Description of the expression. This is a longer text which describes the
* expression, e.g. when hovered over it in a UI.
*/
private final String description;
/**
* Optional. String indicating the location of the expression for error reporting, e.g. a file
* name and a position in the file.
*/
private final String location;

public Expr(String expression, String title, String description, String location) {
this.expression = expression;
this.title = title;
this.description = description;
this.location = location;
}

com.google.api.services.bigquery.model.Expr toPb() {
com.google.api.services.bigquery.model.Expr bqExpr =
new com.google.api.services.bigquery.model.Expr();
bqExpr.setExpression(this.expression);
bqExpr.setTitle(this.title);
bqExpr.setDescription(this.description);
bqExpr.setLocation(this.location);
return bqExpr;
}

static Expr fromPb(com.google.api.services.bigquery.model.Expr bqExpr) {
return new Expr(
bqExpr.getExpression(), bqExpr.getTitle(), bqExpr.getDescription(), bqExpr.getLocation());
}

@Override
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include toString() as well as the normal methods like equals and hashcode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, updated to have toString() method.

public int hashCode() {
return Objects.hash(expression, title, description, location);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final Expr other = (Expr) obj;
return Objects.equals(this.expression, other.expression)
&& Objects.equals(this.title, other.title)
&& Objects.equals(this.description, other.description)
&& Objects.equals(this.location, other.location);
}

@Override
public String toString() {
return toPb().toString();
}
}

private Acl(Entity entity, Role role) {
this(entity, role, null);
}

private Acl(Entity entity, Role role, Expr condition) {
this.entity = checkNotNull(entity);
this.role = role;
this.condition = condition;
}

/** @return Returns the entity for this ACL. */
Expand All @@ -582,6 +657,10 @@ public Entity getEntity() {
public Role getRole() {
return role;
}
/** @return Returns the condition specified by this ACL. */
public Expr getCondition() {
return condition;
}

/**
* @return Returns an Acl object.
Expand All @@ -592,6 +671,10 @@ public static Acl of(Entity entity, Role role) {
return new Acl(entity, role);
}

public static Acl of(Entity entity, Role role, Expr condition) {
return new Acl(entity, role, condition);
}

/**
* @param datasetAclEntity
* @return Returns an Acl object for a datasetAclEntity.
Expand All @@ -618,7 +701,7 @@ public static Acl of(Routine routine) {

@Override
public int hashCode() {
return Objects.hash(entity, role);
return Objects.hash(entity, role, condition);
}

@Override
Expand All @@ -635,19 +718,26 @@ public boolean equals(Object obj) {
return false;
}
final Acl other = (Acl) obj;
return Objects.equals(this.entity, other.entity) && Objects.equals(this.role, other.role);
return Objects.equals(this.entity, other.entity)
&& Objects.equals(this.role, other.role)
&& Objects.equals(this.condition, other.condition);
}

Access toPb() {
Access accessPb = entity.toPb();
if (role != null) {
accessPb.setRole(role.name());
}
if (condition != null) {
accessPb.setCondition(condition.toPb());
}
return accessPb;
}

static Acl fromPb(Access access) {
return Acl.of(
Entity.fromPb(access), access.getRole() != null ? Role.valueOf(access.getRole()) : null);
Entity.fromPb(access),
access.getRole() != null ? Role.valueOf(access.getRole()) : null,
access.getCondition() != null ? Expr.fromPb(access.getCondition()) : null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ public static DatasetOption fields(DatasetField... fields) {
return new DatasetOption(
BigQueryRpc.Option.FIELDS, Helper.selector(DatasetField.REQUIRED_FIELDS, fields));
}

public static DatasetOption accessPolicyVersion(Integer accessPolicyVersion) {
return new DatasetOption(BigQueryRpc.Option.ACCESS_POLICY_VERSION, accessPolicyVersion);
}
}

/** Class for specifying dataset delete options. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ enum Option {
REQUESTED_POLICY_VERSION("requestedPolicyVersion"),
TABLE_METADATA_VIEW("view"),
RETRY_OPTIONS("retryOptions"),
BIGQUERY_RETRY_CONFIG("bigQueryRetryConfig");
BIGQUERY_RETRY_CONFIG("bigQueryRetryConfig"),
ACCESS_POLICY_VERSION("accessPolicyVersion");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,23 @@ private void validateRPC() throws BigQueryException, IOException {
public Dataset getDataset(String projectId, String datasetId, Map<Option, ?> options) {
try {
validateRPC();
return bigquery
.datasets()
.get(projectId, datasetId)
.setFields(Option.FIELDS.getString(options))
.setPrettyPrint(false)
.execute();
Integer accessPolicyVersion = null;
for (Map.Entry<Option, ?> entry : options.entrySet()) {
if (entry.getKey() == Option.ACCESS_POLICY_VERSION && entry.getValue() != null) {
accessPolicyVersion = (Integer) entry.getValue();
}
}

Bigquery.Datasets.Get bqGetRequest =
bigquery
.datasets()
.get(projectId, datasetId)
.setFields(Option.FIELDS.getString(options))
.setPrettyPrint(false);
if (accessPolicyVersion != null) {
bqGetRequest.setAccessPolicyVersion(accessPolicyVersion);
}
return bqGetRequest.execute();
} catch (IOException ex) {
BigQueryException serviceException = translate(ex);
if (serviceException.getCode() == HTTP_NOT_FOUND) {
Expand Down Expand Up @@ -174,12 +185,22 @@ public Tuple<String, Iterable<Dataset>> listDatasets(String projectId, Map<Optio
public Dataset create(Dataset dataset, Map<Option, ?> options) {
try {
validateRPC();
return bigquery
.datasets()
.insert(dataset.getDatasetReference().getProjectId(), dataset)
.setPrettyPrint(false)
.setFields(Option.FIELDS.getString(options))
.execute();
Integer accessPolicyVersion = null;
for (Map.Entry<Option, ?> entry : options.entrySet()) {
if (entry.getKey() == Option.ACCESS_POLICY_VERSION && entry.getValue() != null) {
accessPolicyVersion = (Integer) entry.getValue();
}
}
Bigquery.Datasets.Insert bqCreateRequest =
bigquery
.datasets()
.insert(dataset.getDatasetReference().getProjectId(), dataset)
.setPrettyPrint(false)
.setFields(Option.FIELDS.getString(options));
if (accessPolicyVersion != null) {
bqCreateRequest.setAccessPolicyVersion(accessPolicyVersion);
}
return bqCreateRequest.execute();
} catch (IOException ex) {
throw translate(ex);
}
Expand Down Expand Up @@ -276,13 +297,23 @@ public boolean deleteDataset(String projectId, String datasetId, Map<Option, ?>
public Dataset patch(Dataset dataset, Map<Option, ?> options) {
try {
validateRPC();
Integer accessPolicyVersion = null;
for (Map.Entry<Option, ?> entry : options.entrySet()) {
if (entry.getKey() == Option.ACCESS_POLICY_VERSION && entry.getValue() != null) {
accessPolicyVersion = (Integer) entry.getValue();
}
}
DatasetReference reference = dataset.getDatasetReference();
return bigquery
.datasets()
.patch(reference.getProjectId(), reference.getDatasetId(), dataset)
.setPrettyPrint(false)
.setFields(Option.FIELDS.getString(options))
.execute();
Bigquery.Datasets.Patch bqPatchRequest =
bigquery
.datasets()
.patch(reference.getProjectId(), reference.getDatasetId(), dataset)
.setPrettyPrint(false)
.setFields(Option.FIELDS.getString(options));
if (accessPolicyVersion != null) {
bqPatchRequest.setAccessPolicyVersion(accessPolicyVersion);
}
return bqPatchRequest.execute();
} catch (IOException ex) {
throw translate(ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.cloud.bigquery.Acl.Domain;
import com.google.cloud.bigquery.Acl.Entity;
import com.google.cloud.bigquery.Acl.Entity.Type;
import com.google.cloud.bigquery.Acl.Expr;
import com.google.cloud.bigquery.Acl.Group;
import com.google.cloud.bigquery.Acl.IamMember;
import com.google.cloud.bigquery.Acl.Role;
Expand Down Expand Up @@ -136,4 +137,13 @@ public void testOf() {
assertEquals(routine, acl.getEntity());
assertEquals(null, acl.getRole());
}

@Test
public void testOfWithCondition() {
Expr expr = new Expr("expression", "title", "description", "location");
Acl acl = Acl.of(Group.ofAllAuthenticatedUsers(), Role.READER, expr);
Dataset.Access pb = acl.toPb();
assertEquals(acl, Acl.fromPb(pb));
assertEquals(acl.getCondition(), expr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.google.cloud.RetryOption;
import com.google.cloud.ServiceOptions;
import com.google.cloud.Tuple;
import com.google.cloud.bigquery.BigQuery.DatasetOption;
import com.google.cloud.bigquery.BigQuery.JobOption;
import com.google.cloud.bigquery.BigQuery.QueryResultsOption;
import com.google.cloud.bigquery.InsertAllRequest.RowToInsert;
Expand Down Expand Up @@ -572,6 +573,20 @@ public void testCreateDatasetWithSelectedFields() {
verify(bigqueryRpcMock).create(eq(DATASET_INFO_WITH_PROJECT.toPb()), capturedOptions.capture());
}

@Test
public void testCreateDatasetWithAccessPolicy() {
DatasetInfo datasetInfo = DATASET_INFO.setProjectId(OTHER_PROJECT);
DatasetOption datasetOption = DatasetOption.accessPolicyVersion(3);
when(bigqueryRpcMock.create(datasetInfo.toPb(), optionMap(datasetOption)))
.thenReturn(datasetInfo.toPb());
BigQueryOptions bigQueryOptions =
createBigQueryOptionsForProject(OTHER_PROJECT, rpcFactoryMock);
bigquery = bigQueryOptions.getService();
Dataset dataset = bigquery.create(datasetInfo, datasetOption);
assertEquals(new Dataset(bigquery, new DatasetInfo.BuilderImpl(datasetInfo)), dataset);
verify(bigqueryRpcMock).create(datasetInfo.toPb(), optionMap(datasetOption));
}

@Test
public void testGetDataset() {
when(bigqueryRpcMock.getDataset(PROJECT, DATASET, EMPTY_RPC_OPTIONS))
Expand Down
Loading
Loading