Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: expose all the methods of notification (#141)
* feat: expose all the methods of notification

* feat: remove unsed code

* feat: fix review changes

* build: fix require upper bound dependencies errors

* build: fix clirr ignore differences

* feat: implement getNotification inside StorageRpcTestBase class and fix the builds checks
  • Loading branch information
athakor committed Jun 25, 2020
1 parent 81472a4 commit 8dfc0cb
Show file tree
Hide file tree
Showing 14 changed files with 743 additions and 1 deletion.
25 changes: 25 additions & 0 deletions google-cloud-storage/clirr-ignored-differences.xml
Expand Up @@ -26,4 +26,29 @@
<method>com.google.cloud.storage.BucketInfo$Builder deleteLifecycleRules()</method>
<differenceType>7013</differenceType>
</difference>
<difference>
<className>com/google/cloud/storage/Storage</className>
<method>com.google.api.services.storage.model.Notification createNotification(java.lang.String, com.google.cloud.storage.NotificationInfo)</method>
<differenceType>7012</differenceType>
</difference>
<difference>
<className>com/google/cloud/storage/Storage</className>
<method>com.google.api.services.storage.model.Notification getNotification(java.lang.String, java.lang.String)</method>
<differenceType>7012</differenceType>
</difference>
<difference>
<className>com/google/cloud/storage/Storage</className>
<method>java.util.List listNotifications(java.lang.String)</method>
<differenceType>7012</differenceType>
</difference>
<difference>
<className>com/google/cloud/storage/Storage</className>
<method>boolean deleteNotification(java.lang.String, java.lang.String)</method>
<differenceType>7012</differenceType>
</difference>
<difference>
<className>com/google/cloud/storage/spi/v1/StorageRpc</className>
<method>com.google.api.services.storage.model.Notification getNotification(java.lang.String, java.lang.String)</method>
<differenceType>7012</differenceType>
</difference>
</differences>
5 changes: 5 additions & 0 deletions google-cloud-storage/pom.xml
Expand Up @@ -155,6 +155,11 @@
<artifactId>truth</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
Expand Down
@@ -0,0 +1,309 @@
/*
* Copyright 2020 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.google.cloud.storage;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.api.pathtemplate.PathTemplate;
import com.google.api.services.storage.model.Notification;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* Google Storage Notification metadata;
*
* @see <a href="https://cloud.google.com/storage/docs/concepts-techniques#concepts">Concepts and
* Terminology</a>
*/
public class NotificationInfo implements Serializable {

private static final long serialVersionUID = 5725883368559753810L;
private static final PathTemplate PATH_TEMPLATE =
PathTemplate.createWithoutUrlEncoding("projects/{project}/topics/{topic}");

public enum PayloadFormat {
JSON_API_V1,
NONE
}

static final Function<Notification, NotificationInfo> FROM_PB_FUNCTION =
new Function<Notification, NotificationInfo>() {
@Override
public NotificationInfo apply(Notification pb) {
return NotificationInfo.fromPb(pb);
}
};
static final Function<NotificationInfo, Notification> TO_PB_FUNCTION =
new Function<NotificationInfo, Notification>() {
@Override
public Notification apply(NotificationInfo NotificationInfo) {
return NotificationInfo.toPb();
}
};
private final String generatedId;
private final String topic;
private final List<String> eventTypes;
private final Map<String, String> customAttributes;
private final PayloadFormat payloadFormat;
private final String objectNamePrefix;
private final String etag;
private final String selfLink;

public static final class Builder {

private String generatedId;
private String topic;
private List<String> eventTypes;
private Map<String, String> customAttributes;
private PayloadFormat payloadFormat;
private String objectNamePrefix;
private String etag;
private String selfLink;

Builder(String topic) {
this.topic = topic;
}

Builder(NotificationInfo NotificationInfo) {
generatedId = NotificationInfo.generatedId;
etag = NotificationInfo.etag;
selfLink = NotificationInfo.selfLink;
topic = NotificationInfo.topic;
eventTypes = NotificationInfo.eventTypes;
customAttributes = NotificationInfo.customAttributes;
payloadFormat = NotificationInfo.payloadFormat;
objectNamePrefix = NotificationInfo.objectNamePrefix;
}

Builder setGeneratedId(String generatedId) {
this.generatedId = generatedId;
return this;
}

Builder setSelfLink(String selfLink) {
this.selfLink = selfLink;
return this;
}

/** The name of the topic. It must have the format "projects/{project}/topics/{topic}". */
public Builder setTopic(String topic) {
this.topic = topic;
return this;
}

public Builder setPayloadFormat(PayloadFormat payloadFormat) {
this.payloadFormat = payloadFormat;
return this;
}

public Builder setObjectNamePrefix(String objectNamePrefix) {
this.objectNamePrefix = objectNamePrefix;
return this;
}

public Builder setEventTypes(Iterable<String> eventTypes) {
this.eventTypes = eventTypes != null ? ImmutableList.copyOf(eventTypes) : null;
return this;
}

Builder setEtag(String etag) {
this.etag = etag;
return this;
}

public Builder setCustomAttributes(Map<String, String> customAttributes) {
this.customAttributes =
customAttributes != null ? ImmutableMap.copyOf(customAttributes) : null;
return this;
}

public NotificationInfo build() {
checkNotNull(topic);
return new NotificationInfo(this);
}
}

NotificationInfo(Builder builder) {
generatedId = builder.generatedId;
etag = builder.etag;
selfLink = builder.selfLink;
topic = builder.topic;
eventTypes = builder.eventTypes;
customAttributes = builder.customAttributes;
payloadFormat = builder.payloadFormat;
objectNamePrefix = builder.objectNamePrefix;
}

/** Returns the service-generated id for the notification. */
public String getGeneratedId() {
return generatedId;
}

/** Returns the topic to which this subscription publishes. */
public String getTopic() {
return topic;
}

/** Returns the canonical URI of this topic as a string. */
public String getSelfLink() {
return selfLink;
}

/** Returns the desired content of the Payload. */
public PayloadFormat getPayloadFormat() {
return payloadFormat;
}

/** Returns the object name prefix for which this notification configuration applies. */
public String getObjectNamePrefix() {
return objectNamePrefix;
}

/**
* Returns HTTP 1.1 Entity tag for the notification.
*
* @see <a href="http://tools.ietf.org/html/rfc2616#section-3.11">Entity Tags</a>
*/
public String getEtag() {
return etag;
}

/**
* Returns the list of event types that this notification will apply to. If empty, notifications
* will be sent on all event types.
*
* @see <a href="https://cloud.google.com/storage/docs/cross-origin">Cross-Origin Resource Sharing
* (CORS)</a>
*/
public List<String> getEventTypes() {
return eventTypes;
}

/**
* Returns the list of additional attributes to attach to each Cloud PubSub message published for
* this notification subscription.
*
* @see <a href="https://cloud.google.com/storage/docs/access-control#About-Access-Control-Lists">
* About Access Control Lists</a>
*/
public Map<String, String> getCustomAttributes() {
return customAttributes;
}

/** Returns a builder for the current notification. */
public Builder toBuilder() {
return new Builder(this);
}

@Override
public int hashCode() {
return Objects.hash(getTopic());
}

@Override
public boolean equals(Object obj) {
return obj == this
|| obj != null
&& obj.getClass().equals(NotificationInfo.class)
&& Objects.equals(toPb(), ((NotificationInfo) obj).toPb());
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("topic", getTopic()).toString();
}

Notification toPb() {
Notification notificationPb = new Notification();
notificationPb.setId(generatedId);
notificationPb.setEtag(etag);
if (customAttributes != null) {
notificationPb.setCustomAttributes(customAttributes);
}
if (eventTypes != null) {
notificationPb.setEventTypes(eventTypes);
}
if (objectNamePrefix != null) {
notificationPb.setObjectNamePrefix(objectNamePrefix);
}
if (payloadFormat != null) {
notificationPb.setPayloadFormat(payloadFormat.toString());
} else {
notificationPb.setPayloadFormat(PayloadFormat.NONE.toString());
}
notificationPb.setSelfLink(selfLink);
notificationPb.setTopic(topic);

return notificationPb;
}

/**
* Creates a {@code NotificationInfo} object for the provided topic name.
*
* @param topic The name of the topic. It must have the format
* "projects/{project}/topics/{topic}".
*/
public static NotificationInfo of(String topic) {
PATH_TEMPLATE.validatedMatch(topic, "topic name must be in valid format");
return newBuilder(topic).build();
}

/**
* Returns a {@code NotificationInfo} builder where the topic's name is set to the provided name.
*
* @param topic The name of the topic. It must have the format
* "projects/{project}/topics/{topic}".
*/
public static Builder newBuilder(String topic) {
PATH_TEMPLATE.validatedMatch(topic, "topic name must be in valid format");
return new Builder(topic);
}

static NotificationInfo fromPb(Notification notificationPb) {
Builder builder = newBuilder(notificationPb.getTopic());
if (notificationPb.getId() != null) {
builder.setGeneratedId(notificationPb.getId());
}
if (notificationPb.getEtag() != null) {
builder.setEtag(notificationPb.getEtag());
}
if (notificationPb.getCustomAttributes() != null) {
builder.setCustomAttributes(notificationPb.getCustomAttributes());
}
if (notificationPb.getSelfLink() != null) {
builder.setSelfLink(notificationPb.getSelfLink());
}
if (notificationPb.getObjectNamePrefix() != null) {
builder.setObjectNamePrefix(notificationPb.getObjectNamePrefix());
}
if (notificationPb.getTopic() != null) {
builder.setTopic(notificationPb.getTopic());
}
if (notificationPb.getEventTypes() != null) {
builder.setEventTypes(notificationPb.getEventTypes());
}
if (notificationPb.getPayloadFormat() != null) {
builder.setPayloadFormat(PayloadFormat.valueOf(notificationPb.getPayloadFormat()));
}
return builder.build();
}
}
Expand Up @@ -21,6 +21,7 @@

import com.google.api.core.InternalExtensionOnly;
import com.google.api.gax.paging.Page;
import com.google.api.services.storage.model.Notification;
import com.google.auth.ServiceAccountSigner;
import com.google.auth.ServiceAccountSigner.SigningException;
import com.google.cloud.FieldSelector;
Expand Down Expand Up @@ -3433,4 +3434,36 @@ List<Boolean> testIamPermissions(
* @throws StorageException upon failure
*/
ServiceAccount getServiceAccount(String projectId);

/**
* Creates a notification with the specified entity on the specified bucket.
*
* @return the notification that was created.
* @throws StorageException upon failure
*/
Notification createNotification(String bucket, NotificationInfo notification);

/**
* Get the notification with the specified name on the specified object.
*
* @return the notification object that exist on the bucket.
* @throws StorageException upon failure
*/
Notification getNotification(String bucket, String notification);

/**
* List the notifications for the provided bucket.
*
* @return a list of {@link Notification} objects that exist on the bucket.
* @throws StorageException upon failure
*/
List<Notification> listNotifications(String bucket);

/**
* Deletes the notification with the specified name on the specified object.
*
* @return {@code true} if the notification was deleted, {@code false} if it was not found
* @throws StorageException upon failure
*/
boolean deleteNotification(String bucket, String notification);
}

0 comments on commit 8dfc0cb

Please sign in to comment.