JCLOUDS-458: Addressing suggestions in PR-31

minor changes

minor changes

minor changes

minor changes

Added ErrorHandler with tests

Changed BucketApi method descriptions

Minor change in error handler
This commit is contained in:
hsbhathiya 2014-07-06 23:15:06 +05:30 committed by Matt Stephenson
parent 4e4558cf18
commit 1f3517380f
35 changed files with 526 additions and 288 deletions

View File

@ -111,7 +111,7 @@
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5> <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.google-cloud-storage.identity>${test.google-cloud-storage.identity}</test.google-cloud-storage.identity> <test.google-cloud-storage.identity>${test.google-cloud-storage.identity}</test.google-cloud-storage.identity>
<test.google-cloud-storage.credential>${test.google-cloud-storage.credential}</test.google-cloud-storage.credential> <test.google-cloud-storage.credential>${test.google-cloud-storage.credential}</test.google-cloud-storage.credential>
<test.google-cloud-storage.project-number>${test.google-cloud-storage.project-number}</test.google-cloud-storage.project-number> <test.google-cloud-storage.project-number>${test.google-cloud-storage.project-number}</test.google-cloud-storage.project-number>
<test.google-cloud-storage.api-version>${test.google-cloud-storage.api-version}</test.google-cloud-storage.api-version> <test.google-cloud-storage.api-version>${test.google-cloud-storage.api-version}</test.google-cloud-storage.api-version>
<test.google-cloud-storage.build-version>${test.google-cloud-storage.build-version}</test.google-cloud-storage.build-version> <test.google-cloud-storage.build-version>${test.google-cloud-storage.build-version}</test.google-cloud-storage.build-version>
</systemPropertyVariables> </systemPropertyVariables>

View File

@ -51,5 +51,5 @@ public interface GoogleCloudStorageApi extends Closeable {
*/ */
@Delegate @Delegate
@Path("") @Path("")
BucketApi getBucketsApi(); BucketApi getBucketApi();
} }

View File

@ -17,6 +17,11 @@
package org.jclouds.googlecloudstorage.config; package org.jclouds.googlecloudstorage.config;
import org.jclouds.googlecloudstorage.GoogleCloudStorageApi; import org.jclouds.googlecloudstorage.GoogleCloudStorageApi;
import org.jclouds.googlecloudstorage.handlers.GoogleCloudStorageErrorHandler;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule; import org.jclouds.rest.config.HttpApiModule;
@ -27,4 +32,12 @@ import org.jclouds.rest.config.HttpApiModule;
public class GoogleCloudStorageHttpApiModule extends HttpApiModule<GoogleCloudStorageApi> { public class GoogleCloudStorageHttpApiModule extends HttpApiModule<GoogleCloudStorageApi> {
public GoogleCloudStorageHttpApiModule() { public GoogleCloudStorageHttpApiModule() {
} }
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GoogleCloudStorageErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(GoogleCloudStorageErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoogleCloudStorageErrorHandler.class);
}
} }

View File

@ -18,9 +18,9 @@ package org.jclouds.googlecloudstorage.config;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.googlecloudstorage.domain.BucketTemplate;
import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.oauth.v2.domain.ClaimSet; import org.jclouds.oauth.v2.domain.ClaimSet;
@ -29,6 +29,10 @@ import org.jclouds.oauth.v2.json.ClaimSetTypeAdapter;
import org.jclouds.oauth.v2.json.HeaderTypeAdapter; import org.jclouds.oauth.v2.json.HeaderTypeAdapter;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -43,6 +47,46 @@ public class GoogleCloudStorageParserModule extends AbstractModule {
@Singleton @Singleton
public Map<Type, Object> provideCustomAdapterBindings() { public Map<Type, Object> provideCustomAdapterBindings() {
return new ImmutableMap.Builder<Type, Object>().put(Header.class, new HeaderTypeAdapter()) return new ImmutableMap.Builder<Type, Object>().put(Header.class, new HeaderTypeAdapter())
.put(ClaimSet.class, new ClaimSetTypeAdapter()).build(); .put(ClaimSet.class, new ClaimSetTypeAdapter())
.put(BucketTemplate.class, new BucketTemplateTypeAdapter())
.build();
} }
@Singleton
private static class BucketTemplateTypeAdapter implements JsonSerializer<BucketTemplate> {
@Override
public JsonElement serialize(BucketTemplate src, Type typeOfSrc, JsonSerializationContext context) {
BucketTemplateInternal template = new BucketTemplateInternal(src);
JsonObject bucketTemplate = (JsonObject) context.serialize(template, BucketTemplateInternal.class);
// deal with bucketAccessControls
if (!(src.getAcl() == null) && (src.getAcl().isEmpty())) {
bucketTemplate.add("acl", null);
}
// deal with DefaultObjectAccessControls
if (!(src.getDefaultObjectAccessControls() == null) && (src.getDefaultObjectAccessControls().isEmpty())) {
bucketTemplate.add("defaultObjectAccessControls", null);
}
// deal with Cors
if (!(src.getCors() == null) && (src.getCors().isEmpty())) {
bucketTemplate.add("cors", null);
}
return bucketTemplate;
}
private static class BucketTemplateInternal extends BucketTemplate {
private BucketTemplateInternal(BucketTemplate template) {
name(template.getName()).projectNumber(template.getProjectNumber()).acl(template.getAcl())
.defaultObjectAccessControls(template.getDefaultObjectAccessControls()).owner(template.getOwner())
.location(template.getLocation()).website(template.getWebsite()).logging(template.getLogging())
.versioning(template.getVersioning()).cors(template.getCors()).lifeCycle(template.getLifeCycle())
.storageClass(template.getStorageClass());
}
}
}
} }

View File

@ -33,14 +33,14 @@ import org.jclouds.googlecloudstorage.domain.internal.Owner;
import org.jclouds.googlecloudstorage.domain.internal.Versioning; import org.jclouds.googlecloudstorage.domain.internal.Versioning;
import org.jclouds.googlecloudstorage.domain.internal.Website; import org.jclouds.googlecloudstorage.domain.internal.Website;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
* The Bucket represents a bucket in Google Cloud Storage There is a single global namespace shared by all buckets * The Bucket represents a bucket in Google Cloud Storage. There is a single global namespace shared by all buckets.
* *
* @see <a href = " https://developers.google.com/storage/docs/json_api/v1/buckets"/> * @see <a href = " https://developers.google.com/storage/docs/json_api/v1/buckets"/>
*/ */
public class Bucket extends Resource { public class Bucket extends Resource {
@ -60,10 +60,11 @@ public class Bucket extends Resource {
private final BucketLifeCycle lifeCycle; private final BucketLifeCycle lifeCycle;
private final StorageClass storageClass; private final StorageClass storageClass;
public Bucket(String id, URI selfLink, String name, String etag, Long projectNumber, Date timeCreated, private Bucket(String id, URI selfLink, String name, String etag, @Nullable Long projectNumber, Date timeCreated,
Long metageneration, Set<BucketAccessControls> acl, Set<DefaultObjectAccessControls> defaultObjectAcl, Long metageneration, Set<BucketAccessControls> acl, Set<DefaultObjectAccessControls> defaultObjectAcl,
Owner owner, Location location, Website website, Logging logging, Versioning versioning, Set<BucketCors> cors, Owner owner, @Nullable Location location, @Nullable Website website, @Nullable Logging logging,
BucketLifeCycle lifeCycle, StorageClass storageClass) { @Nullable Versioning versioning, Set<BucketCors> cors, @Nullable BucketLifeCycle lifeCycle,
@Nullable StorageClass storageClass) {
super(Kind.BUCKET, id, selfLink, etag); super(Kind.BUCKET, id, selfLink, etag);
this.projectNumber = projectNumber; this.projectNumber = projectNumber;
@ -72,7 +73,7 @@ public class Bucket extends Resource {
this.acl = acl.isEmpty() ? null : acl; this.acl = acl.isEmpty() ? null : acl;
this.defaultObjectAcl = defaultObjectAcl.isEmpty() ? null : defaultObjectAcl; this.defaultObjectAcl = defaultObjectAcl.isEmpty() ? null : defaultObjectAcl;
this.owner = checkNotNull(owner, "Owner"); this.owner = checkNotNull(owner, "Owner");
this.location = checkNotNull(location, "location"); this.location = location;
this.website = website; this.website = website;
this.logging = logging; this.logging = logging;
this.versioning = versioning; this.versioning = versioning;
@ -197,7 +198,6 @@ public class Bucket extends Resource {
public Builder projectNumber(Long projectNumber) { public Builder projectNumber(Long projectNumber) {
this.projectNumber = projectNumber; this.projectNumber = projectNumber;
return this; return this;
} }
public Builder timeCreated(Date timeCreated) { public Builder timeCreated(Date timeCreated) {

View File

@ -23,6 +23,7 @@ import java.net.URI;
import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Role; import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Role;
import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam; import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -33,22 +34,23 @@ import com.google.common.base.Objects;
*/ */
public class BucketAccessControls extends Resource { public class BucketAccessControls extends Resource {
protected final String bucket; private final String bucket;
protected final String entity; private final String entity;
protected final Role role; private final Role role;
protected final String email; private final String email;
protected final String domain; private final String domain;
protected final String entityId; private final String entityId;
protected final ProjectTeam projectTeam; private final ProjectTeam projectTeam;
protected BucketAccessControls(String id, URI selfLink, String etag, String bucket, String entity, String entityId, private BucketAccessControls(@Nullable String id, @Nullable URI selfLink, @Nullable String etag, String bucket,
Role role, String email, String domain, ProjectTeam projectTeam) { String entity, @Nullable String entityId, Role role, @Nullable String email, @Nullable String domain,
@Nullable ProjectTeam projectTeam) {
super(Kind.BUCKET_ACCESS_CONTROL, id == null ? (bucket + "/" + entity) : id, selfLink, etag); super(Kind.BUCKET_ACCESS_CONTROL, id == null ? (bucket + "/" + entity) : id, selfLink, etag);
this.bucket = checkNotNull(bucket, "bucket"); this.bucket = checkNotNull(bucket, "bucket");
this.entity = checkNotNull(entity, "entity"); this.entity = checkNotNull(entity, "entity");
this.entityId = entityId; this.entityId = entityId;
this.role = role; this.role = checkNotNull(role, "role");
this.email = email; this.email = email;
this.domain = domain; this.domain = domain;
this.projectTeam = projectTeam; this.projectTeam = projectTeam;
@ -117,13 +119,13 @@ public class BucketAccessControls extends Resource {
public static final class Builder extends Resource.Builder<Builder> { public static final class Builder extends Resource.Builder<Builder> {
protected String bucket; private String bucket;
protected String entity; private String entity;
protected String entityId; private String entityId;
protected Role role; private Role role;
protected String email; private String email;
protected String domain; private String domain;
protected ProjectTeam projectTeam; private ProjectTeam projectTeam;
public Builder bucket(String bucket) { public Builder bucket(String bucket) {
this.bucket = bucket; this.bucket = bucket;

View File

@ -32,18 +32,18 @@ import com.google.common.collect.Sets;
public class BucketTemplate { public class BucketTemplate {
private String name; protected String name;
private Long projectNumber; protected Long projectNumber;
private Set<BucketAccessControls> acl; protected Set<BucketAccessControls> acl = Sets.newHashSet();
private Set<DefaultObjectAccessControls> defaultObjectAccessControls; protected Set<DefaultObjectAccessControls> defaultObjectAccessControls = Sets.newHashSet();
private Owner owner; protected Owner owner;
private Location location; protected Location location;
private Website website; protected Website website;
private Logging logging; protected Logging logging;
private Versioning versioning; protected Versioning versioning;
private Set<BucketCors> cors; protected Set<BucketCors> cors = Sets.newHashSet();
private BucketLifeCycle lifeCycle; protected BucketLifeCycle lifeCycle;
private StorageClass storageClass; protected StorageClass storageClass;
public BucketTemplate name(String name) { public BucketTemplate name(String name) {
this.name = name; this.name = name;
@ -91,54 +91,32 @@ public class BucketTemplate {
} }
public BucketTemplate addAcl(BucketAccessControls bucketAccessControls) { public BucketTemplate addAcl(BucketAccessControls bucketAccessControls) {
if (this.acl == null) {
this.acl = Sets.newLinkedHashSet();
}
this.acl.add(bucketAccessControls); this.acl.add(bucketAccessControls);
return this; return this;
} }
public BucketTemplate acl(Set<BucketAccessControls> acl) { public BucketTemplate acl(Set<BucketAccessControls> acl) {
if (this.acl == null) {
this.acl = Sets.newLinkedHashSet();
}
this.acl.addAll(acl); this.acl.addAll(acl);
return this; return this;
} }
public BucketTemplate addDefaultObjectAccessControls(DefaultObjectAccessControls oac) { public BucketTemplate addDefaultObjectAccessControls(DefaultObjectAccessControls oac) {
if (this.defaultObjectAccessControls == null) {
this.defaultObjectAccessControls = Sets.newLinkedHashSet();
}
this.defaultObjectAccessControls.add(oac); this.defaultObjectAccessControls.add(oac);
return this; return this;
} }
public BucketTemplate defaultObjectAccessControls(Set<DefaultObjectAccessControls> defaultObjectAcl) { public BucketTemplate defaultObjectAccessControls(Set<DefaultObjectAccessControls> defaultObjectAcl) {
if (this.defaultObjectAccessControls == null) {
this.defaultObjectAccessControls = Sets.newLinkedHashSet();
}
this.defaultObjectAccessControls.addAll(defaultObjectAcl); this.defaultObjectAccessControls.addAll(defaultObjectAcl);
return this; return this;
} }
public BucketTemplate addCORS(BucketCors cors) { public BucketTemplate addCORS(BucketCors cors) {
if (this.cors == null) {
this.cors = Sets.newLinkedHashSet();
}
this.cors.add(cors); this.cors.add(cors);
return this; return this;
} }
public BucketTemplate cors(Set<BucketCors> cors) { public BucketTemplate cors(Set<BucketCors> cors) {
if (this.cors == null) {
this.cors = Sets.newLinkedHashSet();
}
this.cors.addAll(cors); this.cors.addAll(cors);
return this; return this;
} }

View File

@ -23,6 +23,7 @@ import java.net.URI;
import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.ObjectRole; import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.ObjectRole;
import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam; import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -33,16 +34,17 @@ import com.google.common.base.Objects;
*/ */
public class DefaultObjectAccessControls extends Resource { public class DefaultObjectAccessControls extends Resource {
protected final String bucket; private final String bucket;
protected final String entity; private final String entity;
protected final ObjectRole role; private final ObjectRole role;
protected final String email; private final String email;
protected final String entityId; private final String entityId;
protected final String domain; private final String domain;
protected final ProjectTeam projectTeam; private final ProjectTeam projectTeam;
protected DefaultObjectAccessControls(String id, URI selfLink, String etag, String bucket, String entity, private DefaultObjectAccessControls(@Nullable String id, @Nullable URI selfLink, @Nullable String etag,
String entityId, ObjectRole role, String email, String domain, ProjectTeam projectTeam) { @Nullable String bucket, String entity, @Nullable String entityId, ObjectRole role, @Nullable String email,
@Nullable String domain, @Nullable ProjectTeam projectTeam) {
super(Kind.OBJECT_ACCESS_CONTROL, id, selfLink, etag); super(Kind.OBJECT_ACCESS_CONTROL, id, selfLink, etag);
this.bucket = bucket; this.bucket = bucket;
@ -117,13 +119,13 @@ public class DefaultObjectAccessControls extends Resource {
public static final class Builder extends Resource.Builder<Builder> { public static final class Builder extends Resource.Builder<Builder> {
protected String bucket; private String bucket;
protected String entity; private String entity;
protected String entityId; private String entityId;
protected ObjectRole role; private ObjectRole role;
protected String email; private String email;
protected String domain; private String domain;
protected ProjectTeam projectTeam; private ProjectTeam projectTeam;
public Builder bucket(String bucket) { public Builder bucket(String bucket) {
this.bucket = bucket; this.bucket = bucket;

View File

@ -25,8 +25,8 @@ import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.ObjectRol
*/ */
public class DefaultObjectAccessControlsTemplate { public class DefaultObjectAccessControlsTemplate {
protected String entity; private String entity;
protected ObjectRole role; private ObjectRole role;
public DefaultObjectAccessControlsTemplate role(ObjectRole role) { public DefaultObjectAccessControlsTemplate role(ObjectRole role) {
this.role = role; this.role = role;

View File

@ -35,16 +35,16 @@ public final class DomainResourceRefferences {
ASIA, EU, US, ASIA_EAST1, US_CENTRAL1, US_CENTRAL2, US_EAST1, US_EAST2, US_EAST3, US_WEST1; ASIA, EU, US, ASIA_EAST1, US_CENTRAL1, US_CENTRAL2, US_EAST1, US_EAST2, US_EAST3, US_WEST1;
public String value() { public String value() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()).toUpperCase(); return name().replace('_', '-');
} }
@Override @Override
public String toString() { public String toString() {
return value().toUpperCase(); return value();
} }
public static Location fromValue(String location) { public static Location fromValue(String location) {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, location.toLowerCase())); return valueOf(location.replace('-', '_'));
} }
} }

View File

@ -35,10 +35,10 @@ import com.google.common.collect.ImmutableSet;
public class ListBucketAccessControls { public class ListBucketAccessControls {
protected final Kind kind; private final Kind kind;
protected final Set<BucketAccessControls> items; private final Set<BucketAccessControls> items;
protected ListBucketAccessControls(Kind kind, Set<BucketAccessControls> items) { private ListBucketAccessControls(Kind kind, Set<BucketAccessControls> items) {
this.kind = checkNotNull(kind, "kind"); this.kind = checkNotNull(kind, "kind");
this.items = checkNotNull(items, "items"); this.items = checkNotNull(items, "items");

View File

@ -35,10 +35,10 @@ import com.google.common.collect.ImmutableSet;
public class ListDefaultObjectAccessControls { public class ListDefaultObjectAccessControls {
protected final Kind kind; private final Kind kind;
protected final Set<DefaultObjectAccessControls> items; private final Set<DefaultObjectAccessControls> items;
protected ListDefaultObjectAccessControls(Kind kind, Set<DefaultObjectAccessControls> items) { private ListDefaultObjectAccessControls(Kind kind, Set<DefaultObjectAccessControls> items) {
this.kind = checkNotNull(kind, "kind"); this.kind = checkNotNull(kind, "kind");
this.items = checkNotNull(items, "items"); this.items = checkNotNull(items, "items");
@ -110,4 +110,3 @@ public class ListDefaultObjectAccessControls {
} }
} }
} }

View File

@ -24,6 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties; import java.beans.ConstructorProperties;
import java.net.URI; import java.net.URI;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.CaseFormat; import com.google.common.base.CaseFormat;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -62,7 +64,7 @@ public class Resource {
protected final String etag; protected final String etag;
@ConstructorProperties({ "kind", "id", "selfLink", "etag" }) @ConstructorProperties({ "kind", "id", "selfLink", "etag" })
protected Resource(Kind kind, String id, URI selfLink, String etag) { protected Resource(Kind kind, @Nullable String id, @Nullable URI selfLink, @Nullable String etag) {
this.kind = checkNotNull(kind, "kind"); this.kind = checkNotNull(kind, "kind");
this.id = id; this.id = id;
this.selfLink = selfLink; this.selfLink = selfLink;

View File

@ -27,7 +27,7 @@ import com.google.common.base.Objects;
public class Action { public class Action {
private final String type; private final String type;
public Action(String type) { private Action(String type) {
this.type = type; this.type = type;
} }
@ -84,9 +84,7 @@ public class Action {
public Builder fromAction(Action in) { public Builder fromAction(Action in) {
return this.type(in.getType()); return this.type(in.getType());
} }
} }
} }

View File

@ -21,8 +21,6 @@ import static com.google.common.base.Objects.toStringHelper;
import java.util.Set; import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -32,31 +30,30 @@ import com.google.common.collect.ImmutableSet;
* @see <a href= "https://developers.google.com/storage/docs/cross-origin" /> * @see <a href= "https://developers.google.com/storage/docs/cross-origin" />
*/ */
public final class BucketCors { public class BucketCors {
private final Set<String> origins; private final Set<String> origin;
private final Set<String> methods; private final Set<String> method;
private final Set<String> responseHeaders; private final Set<String> responseHeader;
private final Integer maxAgeSeconds; private final Integer maxAgeSeconds;
public BucketCors(@Nullable Set<String> origin, @Nullable Set<String> method, @Nullable Set<String> responseHeader, private BucketCors(Set<String> origin, Set<String> method, Set<String> responseHeader,
Integer maxAgeSeconds) { Integer maxAgeSeconds) {
this.origin = origin.isEmpty() ? null : origin;
this.origins = origin == null ? ImmutableSet.<String> of() : origin; this.method = method.isEmpty() ? null : method;
this.methods = method == null ? ImmutableSet.<String> of() : method; this.responseHeader = responseHeader.isEmpty() ? null : responseHeader;
this.responseHeaders = responseHeader == null ? ImmutableSet.<String> of() : responseHeader;
this.maxAgeSeconds = maxAgeSeconds; this.maxAgeSeconds = maxAgeSeconds;
} }
public Set<String> getOrigin() { public Set<String> getOrigin() {
return origins; return origin;
} }
public Set<String> getMethod() { public Set<String> getMethod() {
return methods; return method;
} }
public Set<String> getResponseHeader() { public Set<String> getResponseHeader() {
return responseHeaders; return responseHeader;
} }
public Integer getMaxAgeSeconds() { public Integer getMaxAgeSeconds() {
@ -65,10 +62,9 @@ public final class BucketCors {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(origins, methods, responseHeaders, maxAgeSeconds); return Objects.hashCode(origin, method, responseHeader, maxAgeSeconds);
} }
/* TODO -Check equals */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
@ -76,12 +72,12 @@ public final class BucketCors {
if (obj == null || getClass() != obj.getClass()) if (obj == null || getClass() != obj.getClass())
return false; return false;
BucketCors that = BucketCors.class.cast(obj); BucketCors that = BucketCors.class.cast(obj);
return equal(this.origins, that.origins) && equal(this.methods, that.methods) return equal(this.origin, that.origin) && equal(this.method, that.method)
&& equal(this.responseHeaders, that.responseHeaders) && equal(this.maxAgeSeconds, that.maxAgeSeconds); && equal(this.responseHeader, that.responseHeader) && equal(this.maxAgeSeconds, that.maxAgeSeconds);
} }
protected Objects.ToStringHelper string() { protected Objects.ToStringHelper string() {
return toStringHelper(this).add("origin", origins).add("method", methods).add("responseHeader", responseHeaders) return toStringHelper(this).omitNullValues().add("origin", origin).add("method", method).add("responseHeader", responseHeader)
.add("maxAgeSeconds", maxAgeSeconds); .add("maxAgeSeconds", maxAgeSeconds);
} }
@ -94,40 +90,40 @@ public final class BucketCors {
return new Builder(); return new Builder();
} }
public static final class Builder { public static class Builder {
private ImmutableSet.Builder<String> origins = ImmutableSet.builder(); private ImmutableSet.Builder<String> origin = ImmutableSet.builder();
private ImmutableSet.Builder<String> methods = ImmutableSet.builder(); private ImmutableSet.Builder<String> method = ImmutableSet.builder();
private ImmutableSet.Builder<String> reponseHeaders = ImmutableSet.builder(); private ImmutableSet.Builder<String> reponseHeader = ImmutableSet.builder();
private Integer maxAgeSeconds; private Integer maxAgeSeconds;
public Builder addOrigin(String origin) { public Builder addOrigin(String origin) {
this.origins.add(origin); this.origin.add(origin);
return this; return this;
} }
public Builder origin(Set<String> origin) { public Builder origin(Set<String> origin) {
this.origins.addAll(origin); this.origin.addAll(origin);
return this; return this;
} }
public Builder addMethod(String method) { public Builder addMethod(String method) {
this.methods.add(method); this.method.add(method);
return this; return this;
} }
public Builder method(Set<String> method) { public Builder method(Set<String> method) {
this.methods.addAll(method); this.method.addAll(method);
return this; return this;
} }
public Builder addResponseHeader(String responseHeader) { public Builder addResponseHeader(String responseHeader) {
this.reponseHeaders.add(responseHeader); this.reponseHeader.add(responseHeader);
return this; return this;
} }
public Builder responseHeader(Set<String> responseHeader) { public Builder responseHeaders(Set<String> responseHeaders) {
this.reponseHeaders.addAll(responseHeader); this.reponseHeader.addAll(responseHeaders);
return this; return this;
} }
@ -137,13 +133,13 @@ public final class BucketCors {
} }
public BucketCors build() { public BucketCors build() {
return new BucketCors(this.origins.build(), this.methods.build(), this.reponseHeaders.build(), return new BucketCors(this.origin.build(), this.method.build(), this.reponseHeader.build(),
this.maxAgeSeconds); this.maxAgeSeconds);
} }
public Builder fromCors(BucketCors c) { public Builder fromCors(BucketCors in) {
return this.maxAgeSeconds(c.getMaxAgeSeconds()).origin(c.getOrigin()).method(c.getMethod()) return this.maxAgeSeconds(in.getMaxAgeSeconds()).origin(in.getOrigin()).method(in.getMethod())
.responseHeader(c.getResponseHeader()); .responseHeaders(in.getResponseHeader());
} }
} }

View File

@ -33,11 +33,11 @@ public class BucketLifeCycle {
private final Set<Rule> rules; private final Set<Rule> rules;
public BucketLifeCycle(Set<Rule> rule) { private BucketLifeCycle(Set<Rule> rules) {
this.rules = rule == null ? ImmutableSet.<Rule> of() : rule; this.rules = rules.isEmpty() ? null : rules;
} }
public Set<Rule> getRule() { public Set<Rule> getRules() {
return rules; return rules;
} }
@ -77,6 +77,7 @@ public class BucketLifeCycle {
} }
public static class Builder { public static class Builder {
ImmutableSet.Builder<Rule> rules = ImmutableSet.builder(); ImmutableSet.Builder<Rule> rules = ImmutableSet.builder();
public Builder addRule(Rule rule) { public Builder addRule(Rule rule) {
@ -84,8 +85,8 @@ public class BucketLifeCycle {
return this; return this;
} }
public Builder rule(Set<Rule> rule) { public Builder rule(Set<Rule> rules) {
this.rules.addAll(rule); this.rules.addAll(rules);
return this; return this;
} }
@ -94,8 +95,8 @@ public class BucketLifeCycle {
} }
public Builder fromLifeCycle(BucketLifeCycle in) { public Builder fromLifeCycle(BucketLifeCycle in) {
return this.rule(in.getRule()); return this.rule(in.getRules());
} }
} }
} }

View File

@ -20,6 +20,8 @@ import static com.google.common.base.Objects.toStringHelper;
import java.util.Date; import java.util.Date;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
/** /**
@ -32,7 +34,8 @@ public class Condition {
private final Boolean isLive; private final Boolean isLive;
private final Integer numNewerVersions; private final Integer numNewerVersions;
public Condition(Integer age, Date createdBefore, Boolean isLive, Integer numNewerVersions) { private Condition(@Nullable Integer age, @Nullable Date createdBefore, @Nullable Boolean isLive,
@Nullable Integer numNewerVersions) {
this.age = age; this.age = age;
this.createdBefore = createdBefore; this.createdBefore = createdBefore;
this.isLive = isLive; this.isLive = isLive;

View File

@ -18,6 +18,7 @@ package org.jclouds.googlecloudstorage.domain.internal;
import static com.google.common.base.Objects.equal; import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -28,14 +29,14 @@ import com.google.common.base.Objects;
* @see <a href= "https://developers.google.com/storage/docs/accesslogs" /> * @see <a href= "https://developers.google.com/storage/docs/accesslogs" />
*/ */
public final class Logging { public class Logging {
private final String logBucket; private final String logBucket;
private final String logObjectPrefix; private final String logObjectPrefix;
public Logging(String logBucket, String logObjectPrefix) { private Logging(String logBucket, String logObjectPrefix) {
this.logBucket = logBucket; this.logBucket = checkNotNull(logBucket, "logBucket");
this.logObjectPrefix = logObjectPrefix; this.logObjectPrefix = checkNotNull(logObjectPrefix , "logObjectPrefix");
} }
public String getLogBucket() { public String getLogBucket() {

View File

@ -18,6 +18,9 @@ package org.jclouds.googlecloudstorage.domain.internal;
import static com.google.common.base.Objects.equal; import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -25,13 +28,12 @@ import com.google.common.base.Objects;
* This is an internal object used in both Bucket and Object representation * This is an internal object used in both Bucket and Object representation
*/ */
public final class Owner { public class Owner {
private final String entity; private final String entity;
private final String entityId; private final String entityId;
public Owner(String entity, String entityId) { private Owner(String entity, @Nullable String entityId) {
this.entity = entity; this.entity = checkNotNull(entity, "entity");
this.entityId = entityId; this.entityId = entityId;
} }
@ -59,7 +61,7 @@ public final class Owner {
} }
protected Objects.ToStringHelper string() { protected Objects.ToStringHelper string() {
return toStringHelper(this).omitNullValues().add("entiy", entity).add("entityId", entityId); return toStringHelper(this).omitNullValues().add("entity", entity).add("entityId", entityId);
} }
@Override @Override

View File

@ -19,8 +19,6 @@ package org.jclouds.googlecloudstorage.domain.internal;
import static com.google.common.base.Objects.equal; import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Objects.toStringHelper;
import java.beans.ConstructorProperties;
import com.google.common.base.Objects; import com.google.common.base.Objects;
/** /**
@ -31,14 +29,27 @@ import com.google.common.base.Objects;
public final class ProjectTeam { public final class ProjectTeam {
public enum Team { public enum Team {
owners, editors, viewers; OWNERS, EDITORS, VIEWERS;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static Team fromValue(String team) {
return valueOf(team.toUpperCase());
}
} }
private final String projectId; private final String projectId;
private final Team team; private final Team team;
@ConstructorProperties({ "projectId", "team" })
public ProjectTeam(String projectId, Team team) { private ProjectTeam(String projectId, Team team) {
this.projectId = projectId; this.projectId = projectId;
this.team = team; this.team = team;
} }
@ -75,6 +86,10 @@ public final class ProjectTeam {
return string().toString(); return string().toString();
} }
public static Builder builder() {
return new Builder();
}
public static class Builder { public static class Builder {
private String projectId; private String projectId;

View File

@ -17,6 +17,7 @@
package org.jclouds.googlecloudstorage.domain.internal; package org.jclouds.googlecloudstorage.domain.internal;
import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -29,9 +30,9 @@ public class Rule {
private final Action action; private final Action action;
private final Condition condition; private final Condition condition;
public Rule(Action action, Condition condition) { private Rule(Action action, Condition condition) {
this.action = action; this.action = checkNotNull(action, "action");
this.condition = condition; this.condition = checkNotNull(condition, "condition");
} }
public Action getAction() { public Action getAction() {

View File

@ -29,7 +29,7 @@ import com.google.common.base.Objects;
public final class Versioning { public final class Versioning {
private final Boolean enabled; private final Boolean enabled;
public Versioning(Boolean enabled) { private Versioning(Boolean enabled) {
this.enabled = enabled; this.enabled = enabled;
} }

View File

@ -19,6 +19,8 @@ package org.jclouds.googlecloudstorage.domain.internal;
import static com.google.common.base.Objects.equal; import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Objects.toStringHelper;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects; import com.google.common.base.Objects;
/** /**
@ -28,11 +30,10 @@ import com.google.common.base.Objects;
*/ */
public class Website { public class Website {
private final String mainPageSuffix; private final String mainPageSuffix;
private final String notFoundPage; private final String notFoundPage;
public Website(String mainPageSuffix, String notFoundPage) { private Website(@Nullable String mainPageSuffix, @Nullable String notFoundPage) {
this.mainPageSuffix = mainPageSuffix; this.mainPageSuffix = mainPageSuffix;
this.notFoundPage = notFoundPage; this.notFoundPage = notFoundPage;

View File

@ -41,7 +41,6 @@ import org.jclouds.googlecloudstorage.options.GetBucketOptions;
import org.jclouds.googlecloudstorage.options.InsertBucketOptions; import org.jclouds.googlecloudstorage.options.InsertBucketOptions;
import org.jclouds.googlecloudstorage.options.ListOptions; import org.jclouds.googlecloudstorage.options.ListOptions;
import org.jclouds.googlecloudstorage.options.UpdateBucketOptions; import org.jclouds.googlecloudstorage.options.UpdateBucketOptions;
import org.jclouds.http.HttpResponse;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.oauth.v2.config.OAuthScopes; import org.jclouds.oauth.v2.config.OAuthScopes;
import org.jclouds.oauth.v2.filters.OAuthAuthenticator; import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
@ -57,7 +56,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
/** /**
* Provides access to Bucket entities via their REST API. * Provides access to Bucket entities via their REST API.
* *
* @see <a href = " https://developers.google.com/storage/docs/json_api/v1/buckets"/> * @see <a href = "https://developers.google.com/storage/docs/json_api/v1/buckets"/>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@ -72,7 +71,6 @@ public interface BucketApi {
* *
* @return a {@link Bucket} resource * @return a {@link Bucket} resource
*/ */
@Named("Bucket:get") @Named("Bucket:get")
@GET @GET
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -81,7 +79,7 @@ public interface BucketApi {
@OAuthScopes(STORAGE_READONLY_SCOPE) @OAuthScopes(STORAGE_READONLY_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
Bucket getBuckets(@PathParam("bucket") String bucketName); Bucket getBucket(@PathParam("bucket") String bucketName);
/** /**
* Returns metadata for the specified bucket * Returns metadata for the specified bucket
@ -93,7 +91,6 @@ public interface BucketApi {
* *
* @return a {@link Bucket} resource * @return a {@link Bucket} resource
*/ */
@Named("Bucket:get") @Named("Bucket:get")
@GET @GET
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -102,7 +99,7 @@ public interface BucketApi {
@OAuthScopes(STORAGE_READONLY_SCOPE) @OAuthScopes(STORAGE_READONLY_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
Bucket getBuckets(@PathParam("bucket") String bucketName, GetBucketOptions options); Bucket getBucket(@PathParam("bucket") String bucketName, GetBucketOptions options);
/** /**
* Creates a new bucket * Creates a new bucket
@ -110,90 +107,78 @@ public interface BucketApi {
* @param projectId * @param projectId
* A valid API project identifier * A valid API project identifier
* @param bucketTemplate * @param bucketTemplate
* In the request body, supply a bucket resource * supply a {@link BucketTemplate} resource
* *
* @return If successful, this method returns a {@link Bucket} resource in the response body * @return If successful, this method returns a {@link Bucket} resource.
*/ */
@Named("Bucket:insert") @Named("Bucket:insert")
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/b") @Path("/b")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@MapBinder(BucketBinder.class) @MapBinder(BucketBinder.class)
Bucket createBuckets(@QueryParam("project") String projectId, Bucket createBucket(@QueryParam("project") String projectId, @PayloadParam("template") BucketTemplate bucketTemplate);
@PayloadParam("template") BucketTemplate bucketTemplate);
/** /**
* Creates a new Bucket * Creates a new Bucket
* *
* @param projectNumber * @param projectId
* A valid API project identifier * A valid API project identifier
* *
* @param bucketTemplate * @param bucketTemplate
* In the request body, supply a {@link Bucket} resource * Supply a {@link BucketTemplate} resource
* @param options * @param options
* Supply {@link InsertBucketOptions} with optional query parameters * Supply {@link InsertBucketOptions} with optional query parameters
* *
* @return If successful, this method returns a {@link Bucket} resource in the response body * @return If successful, this method returns a {@link Bucket} resource.
*/ */
@Named("Bucket:insert") @Named("Bucket:insert")
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/b") @Path("/b")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@MapBinder(BucketBinder.class) @MapBinder(BucketBinder.class)
Bucket createBuckets(@QueryParam("project") String projectNumber, Bucket createBucket(@QueryParam("project") String projectId,
@PayloadParam("template") BucketTemplate bucketTemplate, InsertBucketOptions options); @PayloadParam("template") BucketTemplate bucketTemplate, InsertBucketOptions options);
/** /**
* Permanently deletes an empty Bucket * Permanently deletes an empty Bucket.If bucket is not empty 409 error to indicate the conflict.
* *
* @param bucketName * @param bucketName
* Name of the bucket * Name of the bucket
*
* @return If successful, this method returns an empty response body
*/ */
@Named("Bucket:delete") @Named("Bucket:delete")
@DELETE @DELETE
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
HttpResponse deleteBuckets(@PathParam("bucket") String bucketName); void deleteBucket(@PathParam("bucket") String bucketName);
/** /**
* Permanently deletes an empty Bucket * Permanently deletes an empty Bucket.If bucket is not empty 409 error to indicate the conflict.
* *
* @param bucketName * @param bucketName
* Name of the bucket * Name of the bucket
* @param options * @param options
* Supply {@link DeleteBucketOptions} with optional query parameters * Supply {@link DeleteBucketOptions} with optional query parameters
*
* @return If successful, this method returns an empty response body.
*/ */
@Named("Bucket:delete") @Named("Bucket:delete")
@DELETE @DELETE
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
HttpResponse deleteBuckets(@PathParam("bucket") String bucketName, DeleteBucketOptions options); void deleteBucket(@PathParam("bucket") String bucketName, DeleteBucketOptions options);
/** /**
* Retrieves a list of buckets for a given project * Retrieves a list of buckets for a given project
* *
* @param project * @param projectId
* Name of the project to retrieve the buckets * A valid API project identifier
* *
* @return a {@link ListPage<Bucket>} * @return a {@link ListPage<Bucket>}
*/ */
@Named("Bucket:list") @Named("Bucket:list")
@GET @GET
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -202,19 +187,16 @@ public interface BucketApi {
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
ListPage<Bucket> listBuckets(@QueryParam("project") String project); ListPage<Bucket> listBucket(@QueryParam("project") String projectId);
/** /**
* Retrieves a list of buckets for a given project * Retrieves a list of buckets for a given project
* *
* @param project * @param projectId
* Name of the project to retrieve the buckets * A valid API project identifier
* @param options * @param options
* Supply {@link ListOptions} with optional query parameters * Supply {@link ListOptions} with optional query parameters
*
*
*/ */
@Named("Bucket:list") @Named("Bucket:list")
@GET @GET
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -223,19 +205,18 @@ public interface BucketApi {
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
ListPage<Bucket> listBuckets(@QueryParam("project") String project, ListOptions options); ListPage<Bucket> listBucket(@QueryParam("project") String projectId, ListOptions options);
/** /**
* Updates a bucket * Updates a bucket
* *
* @param bucketName * @param bucketName
* Name of the bucket * Name of the bucket
* @param bucket * @param bucketTemplate
* In the request body, supply a bucket resource with list of {@link BucketAccessControls} * Supply a {@link BucketTemplate} resource with list of {@link BucketAccessControls}
* *
* @return If successful, this method returns a {@link Bucket} resource in the response body * @return If successful, this method returns the updated {@link Bucket} resource.
*/ */
@Named("Bucket:update") @Named("Bucket:update")
@PUT @PUT
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -243,20 +224,21 @@ public interface BucketApi {
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
Bucket updateBuckets(@PathParam("bucket") String bucketName, Bucket updateBucket(@PathParam("bucket") String bucketName,
@BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate); @BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate);
/** /**
* Updates a bucket * Updates a bucket
* *
* @param bucketName * @param bucketName
* In the request body, supply a bucket resource with list of {@link BucketAccessControls} (acl[]) * Name of the bucket
* @param bucketTemplate
* Supply a {@link BucketTemplate} resource with list of {@link BucketAccessControls}
* @param options * @param options
* Supply {@link UpdateBucketOptions} with optional query parameters * Supply {@link UpdateBucketOptions} with optional query parameters
* *
* @return If successful,this method returns a {@link Bucket} resource in the response body * @return If successful,this method returns the updated {@link Bucket} resource.
*/ */
@Named("Bucket:update") @Named("Bucket:update")
@PUT @PUT
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -264,20 +246,21 @@ public interface BucketApi {
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
Bucket updateBuckets(@PathParam("bucket") String bucketName, Bucket updateBucket(@PathParam("bucket") String bucketName,
@BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate, UpdateBucketOptions options); @BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate, UpdateBucketOptions options);
/** /**
* Updates a bucket supporting patch semantics. * Updates a bucket supporting patch semantics.
* *
* @param bucketName * @see <a href = "https://developers.google.com/storage/docs/json_api/v1/how-tos/performance#patch"/>
* In the request body, supply a bucket resource with list of {@link BucketAccessControls} (acl[])
* @param bucketTemplate
* In the request body, supply the relevant portions of a bucket resource
* *
* @return If successful, this method returns a {@link Bucket} resource in the response body * @param bucketName
* Name of the bucket
* @param bucketTemplate
* Supply a {@link BucketTemplate} resource with list of {@link BucketAccessControls}
*
* @return If successful, this method returns the updated {@link Bucket} resource.
*/ */
@Named("Bucket:patch") @Named("Bucket:patch")
@PATCH @PATCH
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -285,22 +268,23 @@ public interface BucketApi {
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
Bucket patchBuckets(@PathParam("bucket") String bucketName, Bucket patchBucket(@PathParam("bucket") String bucketName,
@BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate); @BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate);
/** /**
* Updates a bucket supporting patch semantics. * Updates a bucket supporting patch semantics.
* *
* @see <a href = "https://developers.google.com/storage/docs/json_api/v1/how-tos/performance#patch"/>
*
* @param bucketName * @param bucketName
* In the request body, supply a bucket resource with list of {@link BucketAccessControls} (acl[]) * Name of the bucket
* @param bucketTemplate * @param bucketTemplate
* In the request body, supply the relevant portions of a bucket resource * Supply a {@link BucketTemplate} resource with list of {@link BucketAccessControls}
* @param options * @param options
* Supply {@link UpdateBucketOptions} with optional query parameters * Supply {@link UpdateBucketOptions} with optional query parameters
* *
* @return If successful, this method returns a {@link Bucket} resource in the response body * @return If successful, this method returns the updated {@link Bucket} resource.
*/ */
@Named("Bucket:patch") @Named("Bucket:patch")
@PATCH @PATCH
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -308,6 +292,6 @@ public interface BucketApi {
@Path("/b/{bucket}") @Path("/b/{bucket}")
@OAuthScopes(STORAGE_FULLCONTROL_SCOPE) @OAuthScopes(STORAGE_FULLCONTROL_SCOPE)
@Fallback(NullOnNotFoundOr404.class) @Fallback(NullOnNotFoundOr404.class)
Bucket patchBuckets(@PathParam("bucket") String bucketName, Bucket patchBucket(@PathParam("bucket") String bucketName,
@BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate, UpdateBucketOptions options); @BinderParam(BindToJsonPayload.class) BucketTemplate bucketTemplate, UpdateBucketOptions options);
} }

View File

@ -31,9 +31,9 @@ public class BucketBinder implements MapBinder {
private BindToJsonPayload jsonBinder; private BindToJsonPayload jsonBinder;
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) { public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) throws IllegalArgumentException {
BucketTemplate postBucket = (BucketTemplate) postParams.get("template"); BucketTemplate postBucket = (BucketTemplate) postParams.get("template");
return bindToRequest(request, postBucket); return bindToRequest(request, postBucket);
} }
@Override @Override

View File

@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.jclouds.googlecloudstorage.handlers;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import javax.inject.Singleton;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
/**
* This will parse and set an appropriate exception on the command object.
*/
@Singleton
public class GoogleCloudStorageErrorHandler implements HttpErrorHandler {
public void handleError(HttpCommand command, HttpResponse response) {
// it is important to always read fully and close streams
byte[] data = closeClientButKeepContentStream(response);
String message = data != null ? new String(data) : null;
Exception exception = message != null ? new HttpResponseException(command, response, message)
: new HttpResponseException(command, response);
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
response.getStatusLine());
switch (response.getStatusCode()) {
case 401:
case 403:
exception = new AuthorizationException(message, exception);
break;
case 404:
exception = new ResourceNotFoundException(message, exception);
break;
case 409:
exception = new IllegalStateException(message, exception);
break;
}
command.setException(exception);
}
}

View File

@ -73,9 +73,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
public void testGetBucketWithNoOptionsResponseIs2xx() throws Exception { public void testGetBucketWithNoOptionsResponseIs2xx() throws Exception {
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE,
GET_BUCKET_REQUEST, BUCKET_RESPONSE).getBucketsApi(); GET_BUCKET_REQUEST, BUCKET_RESPONSE).getBucketApi();
assertEquals(api.getBuckets(EXPECTED_TEST_BUCKET), new NoAclBucketTest().expected()); assertEquals(api.getBucket(EXPECTED_TEST_BUCKET), new NoAclBucketTest().expected());
} }
public void testGetBucketResponseIs4xx() throws Exception { public void testGetBucketResponseIs4xx() throws Exception {
@ -83,40 +83,40 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
HttpResponse getResponse = HttpResponse.builder().statusCode(404).build(); HttpResponse getResponse = HttpResponse.builder().statusCode(404).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE,
GET_BUCKET_REQUEST, getResponse).getBucketsApi(); GET_BUCKET_REQUEST, getResponse).getBucketApi();
assertNull("404", api.getBuckets(EXPECTED_TEST_BUCKET)); assertNull("404", api.getBucket(EXPECTED_TEST_BUCKET));
} }
// Test getBucket with options // Test getBucket with options
public void testGetBucketWithOptionsResponseIs2xx() throws Exception { public void testGetBucketWithOptionsResponseIs2xx() throws Exception {
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_READONLY_SCOPE), TOKEN_RESPONSE,
GET_BUCKET_REQUEST_WITHOPTIONS, BUCKET_RESPONSE).getBucketsApi(); GET_BUCKET_REQUEST_WITHOPTIONS, BUCKET_RESPONSE).getBucketApi();
GetBucketOptions options = new GetBucketOptions().ifMetagenerationNotMatch(Long.valueOf(100)).projection( GetBucketOptions options = new GetBucketOptions().ifMetagenerationNotMatch(Long.valueOf(100)).projection(
Projection.FULL); Projection.FULL);
assertEquals(api.getBuckets(EXPECTED_TEST_BUCKET, options), new NoAclBucketTest().expected()); assertEquals(api.getBucket(EXPECTED_TEST_BUCKET, options), new NoAclBucketTest().expected());
} }
// Test listBucket without options // Test listBucket without options
public void testListBucketWithNoOptionsResponseIs2xx() throws Exception { public void testListBucketWithNoOptionsResponseIs2xx() throws Exception {
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
LIST_BUCKET_REQUEST, LIST_BUCKET_RESPONSE).getBucketsApi(); LIST_BUCKET_REQUEST, LIST_BUCKET_RESPONSE).getBucketApi();
assertEquals(api.listBuckets(EXPECTED_TEST_PROJECT_NUMBER), new NoAclBucketListTest().expected()); assertEquals(api.listBucket(EXPECTED_TEST_PROJECT_NUMBER), new NoAclBucketListTest().expected());
} }
public void testListBucketWithOptionsResponseIs2xx() throws Exception { public void testListBucketWithOptionsResponseIs2xx() throws Exception {
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
LIST_BUCKET_REQUEST_WITHOPTIONS, LIST_BUCKET_RESPONSE).getBucketsApi(); LIST_BUCKET_REQUEST_WITHOPTIONS, LIST_BUCKET_RESPONSE).getBucketApi();
ListOptions options = new ListOptions().maxResults(2).pageToken("jcloudtestbucket500"); ListOptions options = new ListOptions().maxResults(2).pageToken("jcloudtestbucket500");
assertEquals(api.listBuckets(EXPECTED_TEST_PROJECT_NUMBER, options), new NoAclBucketListTest().expected()); assertEquals(api.listBucket(EXPECTED_TEST_PROJECT_NUMBER, options), new NoAclBucketListTest().expected());
} }
@ -124,9 +124,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build(); HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
LIST_BUCKET_REQUEST, listResponse).getBucketsApi(); LIST_BUCKET_REQUEST, listResponse).getBucketApi();
assertNull(api.listBuckets(EXPECTED_TEST_PROJECT_NUMBER)); assertNull(api.listBucket(EXPECTED_TEST_PROJECT_NUMBER));
} }
// Test createBucket without options // Test createBucket without options
@ -143,11 +143,11 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
MediaType.APPLICATION_JSON)).build(); MediaType.APPLICATION_JSON)).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
createRequest, BUCKET_RESPONSE).getBucketsApi(); createRequest, BUCKET_RESPONSE).getBucketApi();
BucketTemplate template = new BucketTemplate().name("bhashbucket"); BucketTemplate template = new BucketTemplate().name("bhashbucket");
assertEquals(api.createBuckets(EXPECTED_TEST_PROJECT_NUMBER, template), new NoAclBucketTest().expected()); assertEquals(api.createBucket(EXPECTED_TEST_PROJECT_NUMBER, template), new NoAclBucketTest().expected());
} }
@ -171,9 +171,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
.payload(staticPayloadFromResource("/bucket_update_response.json")).build(); .payload(staticPayloadFromResource("/bucket_update_response.json")).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
updateRequest, updateResponse).getBucketsApi(); updateRequest, updateResponse).getBucketApi();
assertEquals(api.updateBuckets(EXPECTED_TEST_BUCKET, template), new BucketUpdateTest().expected()); assertEquals(api.updateBucket(EXPECTED_TEST_BUCKET, template), new BucketUpdateTest().expected());
} }
public void testUpdateBucketWithOptionsResponseIs2xx() throws Exception { public void testUpdateBucketWithOptionsResponseIs2xx() throws Exception {
@ -199,9 +199,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
.payload(staticPayloadFromResource("/bucket_update_response.json")).build(); .payload(staticPayloadFromResource("/bucket_update_response.json")).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE,
updateRequest, updateResponse).getBucketsApi(); updateRequest, updateResponse).getBucketApi();
assertEquals(api.updateBuckets(EXPECTED_TEST_BUCKET, template, options), new BucketUpdateTest().expected()); assertEquals(api.updateBucket(EXPECTED_TEST_BUCKET, template, options), new BucketUpdateTest().expected());
} }
public void testPatchBucketWithNoOptionsResponseIs2xx() throws Exception { public void testPatchBucketWithNoOptionsResponseIs2xx() throws Exception {
@ -224,9 +224,9 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
.payload(staticPayloadFromResource("/bucket_update_response.json")).build(); .payload(staticPayloadFromResource("/bucket_update_response.json")).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, patchRequest, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, patchRequest,
patchResponse).getBucketsApi(); patchResponse).getBucketApi();
assertEquals(api.patchBuckets(EXPECTED_TEST_BUCKET, template), new BucketUpdateTest().expected()); assertEquals(api.patchBucket(EXPECTED_TEST_BUCKET, template), new BucketUpdateTest().expected());
} }
public void testPatchBucketWithOptionsResponseIs2xx() throws Exception { public void testPatchBucketWithOptionsResponseIs2xx() throws Exception {
@ -252,8 +252,8 @@ public class BucketApiExpectTest extends BaseGoogleCloudStorageApiExpectTest {
.payload(staticPayloadFromResource("/bucket_update_response.json")).build(); .payload(staticPayloadFromResource("/bucket_update_response.json")).build();
BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, patchRequest, BucketApi api = requestsSendResponses(requestForScopes(STORAGE_FULLCONTROL_SCOPE), TOKEN_RESPONSE, patchRequest,
patchResponse).getBucketsApi(); patchResponse).getBucketApi();
assertEquals(api.updateBuckets(EXPECTED_TEST_BUCKET, template, options), new BucketUpdateTest().expected()); assertEquals(api.updateBucket(EXPECTED_TEST_BUCKET, template, options), new BucketUpdateTest().expected());
} }
} }

View File

@ -43,72 +43,82 @@ import org.jclouds.googlecloudstorage.options.DeleteBucketOptions;
import org.jclouds.googlecloudstorage.options.GetBucketOptions; import org.jclouds.googlecloudstorage.options.GetBucketOptions;
import org.jclouds.googlecloudstorage.options.InsertBucketOptions; import org.jclouds.googlecloudstorage.options.InsertBucketOptions;
import org.jclouds.googlecloudstorage.options.UpdateBucketOptions; import org.jclouds.googlecloudstorage.options.UpdateBucketOptions;
import org.jclouds.http.HttpResponse; import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest { public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
private static final String BUCKET_NAME = "jcloudtestbucket" + (int) (Math.random() * 10000); private static final String BUCKET_NAME = "jcloudstestbucket" + (int) (Math.random() * 10000);
private static final String BUCKET_NAME_WITHOPTIONS = "jcloudtestbucketoptions" + (int) (Math.random() * 10000); private static final String BUCKET_NAME_WITHOPTIONS = "jcloudtestbucketoptions" + (int) (Math.random() * 10000);
private static final String LOG_BUCKET_NAME = "jcloudtestbucket" + (int) (Math.random() * 10000); private static final String LOG_BUCKET_NAME = "jcloudslogbucket" + (int) (Math.random() * 10000);
private Long metageneration; private Long metageneration;
private BucketApi api() { private BucketApi api() {
return api.getBucketsApi(); return api.getBucketApi();
} }
@Test(groups = "live") @Test(groups = "live")
public void testCreateBucket() { public void testCreateBucket() {
BucketTemplate logTemplate = new BucketTemplate().name(LOG_BUCKET_NAME); BucketTemplate logTemplate = new BucketTemplate().name(LOG_BUCKET_NAME);
Bucket logResponse = api().createBuckets(PROJECT_NUMBER, logTemplate); Bucket logResponse = api().createBucket(PROJECT_NUMBER, logTemplate);
assertNotNull(logResponse); assertNotNull(logResponse);
BucketAccessControls acl = BucketAccessControls.builder().bucket(BUCKET_NAME).entity("allUsers").role(Role.OWNER) BucketAccessControls acl = BucketAccessControls.builder().bucket(BUCKET_NAME).entity("allUsers").role(Role.OWNER)
.build(); .build();
DefaultObjectAccessControls oac = DefaultObjectAccessControls.builder().bucket(BUCKET_NAME).entity("allUsers") DefaultObjectAccessControls oac = DefaultObjectAccessControls.builder().bucket(BUCKET_NAME).entity("allUsers")
.role(ObjectRole.OWNER).build(); .role(ObjectRole.OWNER).build();
BucketCors bucketCors = BucketCors.builder().addOrigin("http://example.appspot.com").addMethod("GET").addMethod("HEAD") BucketCors bucketCors = BucketCors.builder().addOrigin("http://example.appspot.com").addMethod("GET")
.addResponseHeader("x-meta-goog-custom").maxAgeSeconds(10).build(); .addMethod("HEAD").addResponseHeader("x-meta-goog-custom").maxAgeSeconds(10).build();
Versioning version = Versioning.builder().enalbled(true).build(); Versioning version = Versioning.builder().enalbled(true).build();
Logging log = new Logging(LOG_BUCKET_NAME, BUCKET_NAME); Logging log = Logging.builder().logBucket(LOG_BUCKET_NAME).logObjectPrefix(BUCKET_NAME).build();
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).addAcl(acl) BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).addAcl(acl).addDefaultObjectAccessControls(oac)
.addDefaultObjectAccessControls(oac).versioning(version).location(Location.US_CENTRAL2).logging(log) .versioning(version).location(Location.US_CENTRAL2).logging(log)
.storageClass(StorageClass.DURABLE_REDUCED_AVAILABILITY).addCORS(bucketCors); .storageClass(StorageClass.DURABLE_REDUCED_AVAILABILITY).addCORS(bucketCors);
Bucket response = api().createBuckets(PROJECT_NUMBER, template); Bucket response = api().createBucket(PROJECT_NUMBER, template);
assertNotNull(response); assertNotNull(response);
assertNotNull(response.getCors()); assertNotNull(response.getCors());
assertTrue(response.getCors().size() == 1);
assertEquals(response.getKind(), Kind.BUCKET); assertEquals(response.getKind(), Kind.BUCKET);
assertEquals(response.getName(), BUCKET_NAME); assertEquals(response.getName(), BUCKET_NAME);
assertEquals(response.getLocation(), Location.US_CENTRAL2); assertEquals(response.getLocation(), Location.US_CENTRAL2);
assertTrue(response.getVersioning().isEnabled()); assertTrue(response.getVersioning().isEnabled());
} }
@Test(groups = "live", dependsOnMethods = { "testCreateBucket" }, expectedExceptions = { IllegalStateException.class })
public void testCreateAlreadyExistBucket() {
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).location(Location.US_CENTRAL2)
.storageClass(StorageClass.DURABLE_REDUCED_AVAILABILITY);
api().createBucket(PROJECT_NUMBER, template);
}
@Test(groups = "live") @Test(groups = "live")
public void testCreateBucketWithOptions() { public void testCreateBucketWithOptions() {
DefaultObjectAccessControls oac = DefaultObjectAccessControls.builder().bucket(BUCKET_NAME_WITHOPTIONS) DefaultObjectAccessControls oac = DefaultObjectAccessControls.builder().bucket(BUCKET_NAME_WITHOPTIONS)
.entity("allUsers").role(ObjectRole.OWNER).build(); .entity("allUsers").role(ObjectRole.OWNER).build();
BucketCors bucketCors = BucketCors.builder().addOrigin("http://example.appspot.com").addMethod("GET").addMethod("HEAD") BucketCors bucketCors = BucketCors.builder().addOrigin("http://example.appspot.com").addMethod("GET")
.addResponseHeader("x-meta-goog-custom").maxAgeSeconds(10).build(); .addMethod("HEAD").addResponseHeader("x-meta-goog-custom").maxAgeSeconds(10).build();
Versioning version = Versioning.builder().enalbled(true).build(); Versioning version = Versioning.builder().enalbled(true).build();
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME_WITHOPTIONS) BucketTemplate template = new BucketTemplate().name(BUCKET_NAME_WITHOPTIONS).addDefaultObjectAccessControls(oac)
.addDefaultObjectAccessControls(oac).versioning(version).location(Location.US_CENTRAL2) .versioning(version).location(Location.US_CENTRAL2)
.storageClass(StorageClass.DURABLE_REDUCED_AVAILABILITY).addCORS(bucketCors); .storageClass(StorageClass.DURABLE_REDUCED_AVAILABILITY).addCORS(bucketCors);
InsertBucketOptions options = new InsertBucketOptions().projection(Projection.FULL); InsertBucketOptions options = new InsertBucketOptions().projection(Projection.FULL);
Bucket response = api().createBuckets(PROJECT_NUMBER, template, options); Bucket response = api().createBucket(PROJECT_NUMBER, template, options);
assertNotNull(response); assertNotNull(response);
assertNotNull(response.getCors()); assertNotNull(response.getCors());
@ -123,7 +133,7 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
BucketAccessControls bucketacl = BucketAccessControls.builder().bucket(BUCKET_NAME) BucketAccessControls bucketacl = BucketAccessControls.builder().bucket(BUCKET_NAME)
.entity("allAuthenticatedUsers").role(Role.OWNER).build(); .entity("allAuthenticatedUsers").role(Role.OWNER).build();
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).addAcl(bucketacl); BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).addAcl(bucketacl);
Bucket response = api().updateBuckets(BUCKET_NAME, template); Bucket response = api().updateBucket(BUCKET_NAME, template);
assertNotNull(response); assertNotNull(response);
assertEquals(response.getName(), BUCKET_NAME); assertEquals(response.getName(), BUCKET_NAME);
@ -136,7 +146,7 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
.entity("allAuthenticatedUsers").role(Role.OWNER).build(); .entity("allAuthenticatedUsers").role(Role.OWNER).build();
UpdateBucketOptions options = new UpdateBucketOptions().projection(Projection.FULL); UpdateBucketOptions options = new UpdateBucketOptions().projection(Projection.FULL);
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME_WITHOPTIONS).addAcl(bucketacl); BucketTemplate template = new BucketTemplate().name(BUCKET_NAME_WITHOPTIONS).addAcl(bucketacl);
Bucket response = api().updateBuckets(BUCKET_NAME_WITHOPTIONS, template, options); Bucket response = api().updateBucket(BUCKET_NAME_WITHOPTIONS, template, options);
assertNotNull(response); assertNotNull(response);
@ -148,7 +158,7 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = "testCreateBucket") @Test(groups = "live", dependsOnMethods = "testCreateBucket")
public void testGetBucket() { public void testGetBucket() {
Bucket response = api().getBuckets(BUCKET_NAME); Bucket response = api().getBucket(BUCKET_NAME);
assertNotNull(response); assertNotNull(response);
assertEquals(response.getName(), BUCKET_NAME); assertEquals(response.getName(), BUCKET_NAME);
@ -158,7 +168,7 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = "testUpdateBucketWithOptions") @Test(groups = "live", dependsOnMethods = "testUpdateBucketWithOptions")
public void testGetBucketWithOptions() { public void testGetBucketWithOptions() {
GetBucketOptions options = new GetBucketOptions().ifMetagenerationMatch(metageneration); GetBucketOptions options = new GetBucketOptions().ifMetagenerationMatch(metageneration);
Bucket response = api().getBuckets(BUCKET_NAME_WITHOPTIONS, options); Bucket response = api().getBucket(BUCKET_NAME_WITHOPTIONS, options);
assertNotNull(response); assertNotNull(response);
assertEquals(response.getName(), BUCKET_NAME_WITHOPTIONS); assertEquals(response.getName(), BUCKET_NAME_WITHOPTIONS);
@ -167,25 +177,25 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = "testCreateBucket") @Test(groups = "live", dependsOnMethods = "testCreateBucket")
public void testListBucket() { public void testListBucket() {
ListPage<Bucket> bucket = api().listBuckets(PROJECT_NUMBER); ListPage<Bucket> bucket = api().listBucket(PROJECT_NUMBER);
Iterator<Bucket> pageIterator = bucket.iterator(); Iterator<Bucket> pageIterator = bucket.iterator();
assertTrue(pageIterator.hasNext()); assertTrue(pageIterator.hasNext());
Bucket singlePageIterator = pageIterator.next(); Bucket iteratedBucket = pageIterator.next();
List<Bucket> bucketAsList = Lists.newArrayList(singlePageIterator); List<Bucket> bucketAsList = Lists.newArrayList(iteratedBucket);
assertNotNull(singlePageIterator); assertNotNull(iteratedBucket);
assertSame(bucketAsList.size(), 1); assertSame(bucketAsList.size(), 1);
} }
@Test(groups = "live", dependsOnMethods = "testCreateBucket") @Test(groups = "live", dependsOnMethods = "testCreateBucket")
public void testPatchBucket() { public void testPatchBucket() {
Logging logging = new Logging(LOG_BUCKET_NAME, BUCKET_NAME); Logging logging = Logging.builder().logBucket(LOG_BUCKET_NAME).logObjectPrefix(BUCKET_NAME).build();
BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).logging(logging); BucketTemplate template = new BucketTemplate().name(BUCKET_NAME).logging(logging);
Bucket response = api().patchBuckets(BUCKET_NAME, template); Bucket response = api().patchBucket(BUCKET_NAME, template);
assertNotNull(response); assertNotNull(response);
assertEquals(response.getName(), BUCKET_NAME); assertEquals(response.getName(), BUCKET_NAME);
@ -194,14 +204,13 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
@Test(groups = "live", dependsOnMethods = { "testListBucket", "testGetBucket", "testUpdateBucket" }) @Test(groups = "live", dependsOnMethods = { "testListBucket", "testGetBucket", "testUpdateBucket" })
public void testDeleteBucket() { public void testDeleteBucket() {
HttpResponse response = api().deleteBuckets(BUCKET_NAME); api().deleteBucket(BUCKET_NAME);
HttpResponse response2 = api().deleteBuckets(LOG_BUCKET_NAME); api().deleteBucket(LOG_BUCKET_NAME);
}
assertNotNull(response);
assertEquals(response.getStatusCode(), 204);
assertNotNull(response2);
assertEquals(response2.getStatusCode(), 204);
@Test(groups = "live", dependsOnMethods = { "testDeleteBucket" }, expectedExceptions = { ResourceNotFoundException.class })
public void testDeleteNotExistingBucket() {
api().deleteBucket(BUCKET_NAME);
} }
@Test(groups = "live", dependsOnMethods = { "testGetBucketWithOptions" }) @Test(groups = "live", dependsOnMethods = { "testGetBucketWithOptions" })
@ -210,10 +219,8 @@ public class BucketApiLiveTest extends BaseGoogleCloudStorageApiLiveTest {
DeleteBucketOptions options = new DeleteBucketOptions().ifMetagenerationMatch(metageneration) DeleteBucketOptions options = new DeleteBucketOptions().ifMetagenerationMatch(metageneration)
.ifMetagenerationNotMatch(metageneration + 1); .ifMetagenerationNotMatch(metageneration + 1);
HttpResponse response = api().deleteBuckets(BUCKET_NAME_WITHOPTIONS, options); api().deleteBucket(BUCKET_NAME_WITHOPTIONS, options);
assertNotNull(response);
assertEquals(response.getStatusCode(), 204);
} }
} }

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.jclouds.googlecloudstorage.handlers;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.EasyMock.verify;
import java.net.URI;
import org.easymock.IArgumentMatcher;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "GoogleStorageErrorHandlerTest")
public class GoogleCloudStorageErrorHandlerTest {
@Test
public void test409MakesIllegalStateException() {
assertCodeMakes("POST", URI.create("https://www.googleapis.com/storage/v1"), 409, "HTTP/1.1 409 Conflict",
"\"{\"code\":\"InvalidState\",\"message\":\"An incompatible transition has already been queued for this"
+ " resource\"}\"", IllegalStateException.class);
}
@Test
public void test401MakesAuthorizationException() {
assertCodeMakes("POST", URI.create("https://www.googleapis.com/storage/v1"), 401, "HTTP/1.1 401 Unauthorized",
"Login Required", AuthorizationException.class);
}
@Test
public void test403MakesAuthorizationException() {
assertCodeMakes("POST", URI.create("https://www.googleapis.com/storage/v1"), 403, "HTTP/1.1 403 Forbidden",
"Login Required", AuthorizationException.class);
}
@Test
public void test404MakesResourceNotFoundException() {
assertCodeMakes("POST", URI.create("https://www.googleapis.com/storage/v1"), 404, "HTTP/1.1 404 Not Found",
"Not Found", ResourceNotFoundException.class);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
Class<? extends Exception> expected) {
assertCodeMakes(method, uri, statusCode, message, "application/json", content, expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
GoogleCloudStorageErrorHandler function = new GoogleCloudStorageErrorHandler();
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = HttpRequest.builder().method(method).endpoint(uri).build();
HttpResponse response = HttpResponse.builder().statusCode(statusCode).message(message).payload(content).build();
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {
@Override
public void appendTo(StringBuffer buffer) {
buffer.append("classEq(");
buffer.append(in);
buffer.append(")");
}
@Override
public boolean matches(Object arg) {
return arg.getClass() == in;
}
});
return null;
}
}

View File

@ -42,8 +42,8 @@ public class BucketAclListTest extends BaseGoogleCloudStorageParseTest<ListBucke
.id("jcloudtestbucket/project-owners-1082289308625") .id("jcloudtestbucket/project-owners-1082289308625")
.selfLink( .selfLink(
URI.create("https://content.googleapis.com/storage/v1/b/jcloudtestbucket/acl/project-owners-1082289308625")) URI.create("https://content.googleapis.com/storage/v1/b/jcloudtestbucket/acl/project-owners-1082289308625"))
.projectTeam(new ProjectTeam("1082289308625", Team.owners)).bucket("jcloudtestbucket") .projectTeam(ProjectTeam.builder().projectId("1082289308625").team(Team.OWNERS).build())
.entity("project-owners-1082289308625").role(Role.OWNER).etag("CAc=").build(); .bucket("jcloudtestbucket").entity("project-owners-1082289308625").role(Role.OWNER).etag("CAc=").build();
@Override @Override
public String resource() { public String resource() {

View File

@ -36,6 +36,7 @@ public class DefaultObjectAclGetTest extends BaseGoogleCloudStorageParseTest<Def
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public DefaultObjectAccessControls expected() { public DefaultObjectAccessControls expected() {
return DefaultObjectAccessControls.builder().entity("project-owners-1082289308625").role(ObjectRole.OWNER) return DefaultObjectAccessControls.builder().entity("project-owners-1082289308625").role(ObjectRole.OWNER)
.etag("CAk=").projectTeam(new ProjectTeam("1082289308625", Team.owners)).build(); .etag("CAk=").projectTeam(ProjectTeam.builder().projectId("1082289308625").team(Team.OWNERS).build())
.build();
} }
} }

View File

@ -33,7 +33,8 @@ public class DefaultObjectAclListTest extends BaseGoogleCloudStorageParseTest<Li
private DefaultObjectAccessControls item_1 = DefaultObjectAccessControls.builder() private DefaultObjectAccessControls item_1 = DefaultObjectAccessControls.builder()
.entity("project-owners-1082289308625").role(ObjectRole.OWNER) .entity("project-owners-1082289308625").role(ObjectRole.OWNER)
.projectTeam(new ProjectTeam("1082289308625", Team.owners)).etag("CAk=").build(); .projectTeam(ProjectTeam.builder().projectId("1082289308625").team(Team.OWNERS).build()).etag("CAk=")
.build();
@Override @Override
public String resource() { public String resource() {

View File

@ -29,6 +29,7 @@ import org.jclouds.googlecloudstorage.domain.Bucket;
import org.jclouds.googlecloudstorage.domain.DefaultObjectAccessControls; import org.jclouds.googlecloudstorage.domain.DefaultObjectAccessControls;
import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Role; import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.Role;
import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.StorageClass; import org.jclouds.googlecloudstorage.domain.DomainResourceRefferences.StorageClass;
import org.jclouds.googlecloudstorage.domain.internal.BucketCors;
import org.jclouds.googlecloudstorage.domain.internal.Owner; import org.jclouds.googlecloudstorage.domain.internal.Owner;
import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam; import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam;
import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam.Team; import org.jclouds.googlecloudstorage.domain.internal.ProjectTeam.Team;
@ -36,16 +37,21 @@ import org.jclouds.googlecloudstorage.internal.BaseGoogleCloudStorageParseTest;
public class FullBucketGetTest extends BaseGoogleCloudStorageParseTest<Bucket> { public class FullBucketGetTest extends BaseGoogleCloudStorageParseTest<Bucket> {
private final BucketAccessControls acl_1 = BucketAccessControls private final BucketAccessControls acl1 = BucketAccessControls
.builder() .builder()
.id("jcloudtestbucket3500/project-owners-1082289308625") .id("jcloudtestbucket3500/project-owners-1082289308625")
.selfLink( .selfLink(
URI.create("https://www.googleapis.com/storage/v1/b/jcloudtestbucket3500/acl/project-owners-1082289308625")) URI.create("https://www.googleapis.com/storage/v1/b/jcloudtestbucket3500/acl/project-owners-1082289308625"))
.bucket("jcloudtestbucket3500").entity("project-owners-1082289308625").role(Role.OWNER) .bucket("jcloudtestbucket3500").entity("project-owners-1082289308625").role(Role.OWNER)
.projectTeam(new ProjectTeam("1082289308625", Team.owners)).etag("CAo=").build(); .projectTeam(ProjectTeam.builder().projectId("1082289308625").team(Team.OWNERS).build()).etag("CAo=")
.build();
private final DefaultObjectAccessControls defObjectAcl = DefaultObjectAccessControls.builder() private final DefaultObjectAccessControls defObjectAcl = DefaultObjectAccessControls.builder()
.entity("project-owners-1082289308625").role(ObjectRole.OWNER).etag("CAo=").build(); .entity("project-owners-1082289308625").role(ObjectRole.OWNER).etag("CAo=").build();
private final BucketCors bucketCors = BucketCors.builder().addOrigin("http://example.appspot.com").addMethod("GET")
.addMethod("HEAD").addResponseHeader("x-meta-goog-custom").maxAgeSeconds(10).build();
@Override @Override
public String resource() { public String resource() {
return "/full_bucket_get.json"; return "/full_bucket_get.json";
@ -59,8 +65,8 @@ public class FullBucketGetTest extends BaseGoogleCloudStorageParseTest<Bucket> {
.name("jcloudtestbucket3500").projectNumber(Long.valueOf("1082289308625")) .name("jcloudtestbucket3500").projectNumber(Long.valueOf("1082289308625"))
.timeCreated(new SimpleDateFormatDateService().iso8601DateParse("2014-06-19T14:03:22.345Z")) .timeCreated(new SimpleDateFormatDateService().iso8601DateParse("2014-06-19T14:03:22.345Z"))
.metageneration(Long.valueOf(10)).owner(Owner.builder().entity("project-owners-1082289308625").build()) .metageneration(Long.valueOf(10)).owner(Owner.builder().entity("project-owners-1082289308625").build())
.location(Location.US).storageClass(StorageClass.STANDARD).etag("CAo=").addAcl(acl_1) .location(Location.US).storageClass(StorageClass.STANDARD).etag("CAo=").addAcl(acl1)
.addDefaultObjectAcl(defObjectAcl).build(); .addDefaultObjectAcl(defObjectAcl).addCORS(bucketCors).build();
} }
} }

View File

@ -32,7 +32,7 @@ import org.jclouds.googlecloudstorage.internal.BaseGoogleCloudStorageParseTest;
public class NoAclBucketListTest extends BaseGoogleCloudStorageParseTest<ListPage<Bucket>> { public class NoAclBucketListTest extends BaseGoogleCloudStorageParseTest<ListPage<Bucket>> {
private Bucket item_1 = Bucket.builder().id("bhashbucket") private Bucket item1 = Bucket.builder().id("bhashbucket")
.selfLink(URI.create("https://content.googleapis.com/storage/v1/b/bhashbucket")).name("bhashbucket") .selfLink(URI.create("https://content.googleapis.com/storage/v1/b/bhashbucket")).name("bhashbucket")
.projectNumber(Long.valueOf("1082289308625")) .projectNumber(Long.valueOf("1082289308625"))
.timeCreated(new SimpleDateFormatDateService().iso8601DateParse("2014-06-02T19:19:41.112z")) .timeCreated(new SimpleDateFormatDateService().iso8601DateParse("2014-06-02T19:19:41.112z"))
@ -47,7 +47,7 @@ public class NoAclBucketListTest extends BaseGoogleCloudStorageParseTest<ListPag
@Override @Override
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public ListPage<Bucket> expected() { public ListPage<Bucket> expected() {
return ListPage.<Bucket> builder().kind(Kind.BUCKETS).nextPageToken("bhashbucket").addItem(item_1).build(); return ListPage.<Bucket> builder().kind(Kind.BUCKETS).nextPageToken("bhashbucket").addItem(item1).build();
} }
} }

View File

@ -29,6 +29,22 @@
"etag": "CAo=" "etag": "CAo="
} }
], ],
"cors": [
{
"maxAgeSeconds": 10,
"origin": [
"http://example.appspot.com"
],
"responseHeader": [
"x-meta-goog-custom"
],
"method": [
"GET",
"HEAD"
]
}
],
"owner": { "owner": {
"entity": "project-owners-1082289308625" "entity": "project-owners-1082289308625"
}, },